CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Sortowanie StringGrinda

Sortowanie StringGrinda

dział ogólny

Sortowanie StringGrinda

Nowy postprzez Boshi » piątek, 14 listopada 2014, 17:32

Mam za zadanie napisać bazę danych w c++ Bulider. Aktualnie pracuję nad wyszukiwaniem liniowym i binarnym. Problem w tym, że oba wymagają uporządkowanych danych. Może ktoś pomóc z sortowaniem?
Co chciałbym; Aby po zaznaczeniu RadioButtona np imie i kliknięciu OK, program posortował wg imienia. Czyli sortowanie w zależności od zaznaczonego RadioButtona.
Avatar użytkownika
Boshi
Bladawiec
Bladawiec
 
Posty: 32
Dołączył(a): piątek, 14 listopada 2014, 17:29
Podziękował : 7
Otrzymał podziękowań: 0
System operacyjny: win 7
Kompilator: Bulider 2006
Gadu Gadu: 0
    Windows 7Firefox

Re: Sortowanie StringGrinda

Nowy postprzez Mironas » piątek, 14 listopada 2014, 18:00

Poradę dotyczącą sortowania StrinGrid-a masz tutaj:
http://programowanie.cal.pl/cyfbar/stri ... tml#grid18

Ale jeśli program wykorzystuje jakąś bazę danych SQL to lepiej będzie (po zmianie pola sortowania) wykonać nowe polecenie SELECT z innym wpisem w sekcji ORDER BY.
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Sortowanie StringGrinda

Nowy postprzez Boshi » piątek, 14 listopada 2014, 18:09

A nie ma czegoś prostszego? Po prostu zwykłe sortowanie (nawet bombelkowe) zależne od wybranego radiobuttona. Z portalu mam;
KOD cpp:     UKRYJ  
void BubbleSort(TStringGrid *Tabela, int Col)
{
 AnsiString temp;
 for(int i = Tabela->FixedRows; i < Tabela->RowCount; i++)
 {
  for(int j = Tabela->FixedRows; j < i; j++)
  {
   if(Tabela->Cells[Col][i] < Tabela->Cells[Col][j])
   {
    temp = Tabela->Rows[i]->GetText();
    Tabela->Rows[i]->SetText(Tabela->Rows[j]->GetText());
    Tabela->Rows[j]->SetText(temp.c_str());
   }
  }
 }
}

Pytanie, jak przekazać jako argument wywołania RadioButtona zamiast int col?

Baza nie ma połączenia z SQL. Zwykła statyczna z opcją losowania rekordów oraz ręcznego dodawania,usuwania itd.
Avatar użytkownika
Boshi
Bladawiec
Bladawiec
 
Posty: 32
Dołączył(a): piątek, 14 listopada 2014, 17:29
Podziękował : 7
Otrzymał podziękowań: 0
System operacyjny: win 7
Kompilator: Bulider 2006
Gadu Gadu: 0
    Windows 7Firefox

Re: Sortowanie StringGrinda

Nowy postprzez Mironas » piątek, 14 listopada 2014, 18:19

KOD cpp:     UKRYJ  
// Po kliknięciu RadioButton1 sortuj wg kolumny nr 1
void __fastcall TForm1::RadioButton1Click(TObject *Sender)
{
  BubbleSort(StringGrid1, 1);
}
//---------------------------------------------------------------------------
// Po kliknięciu RadioButton2 sortuj wg kolumny nr 2
void __fastcall TForm1::RadioButton2Click(TObject *Sender)
{
  BubbleSort(StringGrid1, 2);
}
//---------------------------------------------------------------------------
 

Za ten post autor Mironas otrzymał podziękowanie od:
Boshi
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Sortowanie StringGrinda

Nowy postprzez Boshi » piątek, 14 listopada 2014, 19:00

Dziękuję, nie wpadłem na to, że w taki prosty sposób można to rozwiązać :)
Avatar użytkownika
Boshi
Bladawiec
Bladawiec
 
Posty: 32
Dołączył(a): piątek, 14 listopada 2014, 17:29
Podziękował : 7
Otrzymał podziękowań: 0
System operacyjny: win 7
Kompilator: Bulider 2006
Gadu Gadu: 0
    Windows 7Firefox

Re: Sortowanie StringGrinda

Nowy postprzez Boshi » sobota, 15 listopada 2014, 15:45

Mam jeszcze pytanie odnośnie wyszukiwania połówkowego. Na internecie są co prawda gotowe algorytmy, jednak opierają się one o konsolę. Próbowałem przerobić taki kod by zczytywał z pola Edit wpisane dane, ale nic z tego.
np taki kod. Nie bardzo wiem jak te tablice tutaj pozamieniać na elementy StringGrinda.
KOD cpp:     UKRYJ  
const int N = 100;

int main()
{
  int Z[N],i,ip,ik,isr,k,L,p;

  srand((unsigned)time(NULL));

  // wypełniamy tablicę Z[]

  Z[0] = rand() % 5;
  for(i = 1; i < N; i++) Z[i] = Z[i - 1] + (rand() % 5);

  // generujemy klucz k

  k = Z[0] + (rand() % (Z[N - 1] - Z[0] + 1));

  // poszukujemy binarnie elementu k

  p = -1; L = ip = 0; ik = N - 1;
  while(ip <= ik)
  {
    L++;
    isr = (ip + ik) >> 1;
    if(Z[isr] == k)
    {
      p = isr; break;
    }
    else if(k < Z[isr]) ik = isr - 1;
    else                ip = isr + 1;
  }
Avatar użytkownika
Boshi
Bladawiec
Bladawiec
 
Posty: 32
Dołączył(a): piątek, 14 listopada 2014, 17:29
Podziękował : 7
Otrzymał podziękowań: 0
System operacyjny: win 7
Kompilator: Bulider 2006
Gadu Gadu: 0
    Windows 7Firefox

Re: Sortowanie StringGrinda

Nowy postprzez Mironas » sobota, 15 listopada 2014, 16:07

A po co przepisywać dane ze StringGrida do tablicy?
Możesz od razu pracować na danych w SG tak jak w poprzednim przykładzie.

Rozmiar tablicy (twoje N) to dla SG ilość wierszy RowCount lub ilość kolumn ColCount.
Dostęp do pojedynczego elementu: Cells[k][w], gdzie k oznacza indeks kolumny a w indeks wiersza. Pamiętaj że indeksy kolumn i wierszy zaczynają się od zera.

Pamiętaj też, aby uwzględnić wiersze i kolumny "zafixowane" ;) czyli właściwości FixedCols i FixedRows (w poprzednim przykładzie miałeś to uwzględnione).

Za ten post autor Mironas otrzymał podziękowanie od:
Boshi
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Sortowanie StringGrinda

Nowy postprzez Boshi » sobota, 15 listopada 2014, 16:39

Tak faktycznie ustawiłem poszczególne zmienne jako elementy Stringrida i działa :)

Ostatnie pytanie jeszcze. Mam taki kod zapisujący StringGrida do pliku. Z jakiegoś forum. Działa ok, ale potrzebuje by zamiast podawać jako argument ściżkę do pliku to abym sam ją podawał po przez kontrolkę SaveDialog. nie bardzo interesuję się c++ a bazę na zaliczenie zrobić trzeba i sobie Nauczyciel zażyczył właśnie odczyt i zapis z ręcznie wybranego pliku. Da się to jakoś łatwo przerobić?

KOD cpp:     UKRYJ  
void SaveGridToFile(AnsiString FileName, TStringGrid *Grid)
{
    TStringList *File = new TStringList;
    //zapisuje liczbę wierszy i kolumn (w podobny sposób można zapisać inne informacje o tabeli)
    File->Append("Rows=" + IntToStr(Grid->RowCount));
    File->Append("Cols=" + IntToStr(Grid->ColCount));
    File->Append("[DATA]");//znacznik początku danych
    for(int i = 0; i < Grid->RowCount; ++i)
        File->Append(Grid->Rows[i]->CommaText);//zapisuje cały wiersz (rekord) w jednej linii.

    File->SaveToFile(FileName);
    delete File;
}
Avatar użytkownika
Boshi
Bladawiec
Bladawiec
 
Posty: 32
Dołączył(a): piątek, 14 listopada 2014, 17:29
Podziękował : 7
Otrzymał podziękowań: 0
System operacyjny: win 7
Kompilator: Bulider 2006
Gadu Gadu: 0
    Windows 7Firefox

Re: Sortowanie StringGrinda

Nowy postprzez Mironas » sobota, 15 listopada 2014, 17:10

Wywołaj swoją funkcję w ten sposób:
KOD cpp:     UKRYJ  
  if ( SaveDialog1->Execute() )
    SaveGridToFile(SaveDialog1->FileName, StringGrid1);
 

Za ten post autor Mironas otrzymał podziękowanie od:
Boshi
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Sortowanie StringGrinda

Nowy postprzez Boshi » sobota, 15 listopada 2014, 17:24

Dziękuję, wszystko działa jak należy. Byłęm pewny, że trzeba coś w kodzie sam funkcji zmienić :)
Avatar użytkownika
Boshi
Bladawiec
Bladawiec
 
Posty: 32
Dołączył(a): piątek, 14 listopada 2014, 17:29
Podziękował : 7
Otrzymał podziękowań: 0
System operacyjny: win 7
Kompilator: Bulider 2006
Gadu Gadu: 0
    Windows 7Firefox

Re: Sortowanie StringGrinda

Nowy postprzez Boshi » niedziela, 16 listopada 2014, 13:30

Dobra to jeszcze pytanie odnośnie tego binarnego, bo wczoraj byłem pewny, że coś działa, a dziś na świeżym umyślę patrzę a to jednak nie to ;D

Wyrzuca exceptiona ponieważ wartość l i p nie są liczbami. Algorytm opiera się oczywiście o dzieleie na pół całości. Pytanie jak podzielić komórki stringa? Skoro cała kolumna imię jest posortowana?
Chyba, że zaszedłem z logiką zbyt daleko i jedynie co potrzebuje to posortowanej kolumny ID którą wstawiam za L i P wyznaczam połówkę i dalej wyszukuje?

KOD cpp:     UKRYJ  
int s;
    String l=(Form1->tabela->Cells[1][1]);

     String p= (Form1->tabela->Cells[1][Form1->tabela->RowCount-1]);
       ShowMessage(l);
       ShowMessage(p);

      while (true)
{
if (l > p)
{
ShowMessage("Nie odnaleziono");
break;
}
//s = StrToInt(l+p)/2;   // tutaj jest exception ponieważ dodaje dwa stringi a wymaga  inta.
if (Form1->tabela->Cells[1][s] == Edit2->Text)
{
ShowMessage("odnaleziono");
break;
}
else if (Form1->tabela->Cells[1][s] < Edit2->Text)
l = s+1;
else
p = s-1;
}
Avatar użytkownika
Boshi
Bladawiec
Bladawiec
 
Posty: 32
Dołączył(a): piątek, 14 listopada 2014, 17:29
Podziękował : 7
Otrzymał podziękowań: 0
System operacyjny: win 7
Kompilator: Bulider 2006
Gadu Gadu: 0
    Windows 7Firefox

Re: Sortowanie StringGrinda

Nowy postprzez Cyfrowy Baron » niedziela, 16 listopada 2014, 15:24

Wyrzca ci błąd nie dlatego, że dodajesz dwa String'i lecz dlatego, że próbujesz przekonwertować tekst nie będący liczbą na liczbę. Dodanie dwóch tekstów, np: "Cyfrowy" + "Baron" da efekt "CyfrowyBaron".
Spróbuj z funkcją StrToIntDef(String Text, Int Wartość domyślna);

KOD cpp:     UKRYJ  
StrToInt(l+p, 1) / 2;


Oczywiście to może skutkować tym, że kolumna nie zostanie posortowana prawidłowo, ale unikniesz błędów.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows 7Firefox

Re: Sortowanie StringGrinda

Nowy postprzez Boshi » niedziela, 16 listopada 2014, 16:02

No dobrze, błędu nie ma, ale chyba gubię logikę algorytmu.

Tutaj mam zapisaną posortowaną kolumnę Imię. Zatem
L=pierwsze imię w kolumnie imię; np Ada
P= ostatnie imię w kolumnie imie; np Zelisław
KOD cpp:     UKRYJ  
 String l=(Form1->tabela->Cells[1][1]);
 String p= (Form1->tabela->Cells[1][Form1->tabela->RowCount-1]);


Pytanie skąd algorytm po dodaniu tych dwóch słów i podzieleniu ma wiedzieć które jest mniejsze a które większe skoro są to stringi ?
KOD cpp:     UKRYJ  
StrToIntDef(l+p, 1) / 2
; np Ada+Zdzisiał/2 = ??? bezsens wydaje mi sie.

Czy ten algorytm nie powinien opierać się o same ID? tzn mam np Id w zakresie 1-101. po podzieleniu dostajemy nr id=51 no i w sumie też nic nam to nie daje, bo jak przyrównać otrzymane ID do wpisanego tekstu z Edita? Bezsens. Mógłby ktoś podać jak to wyszukiwanie powinno wyglądać dla stringów ? np znaleźć imię karol we wszystkich wylosowanych imionach?
Avatar użytkownika
Boshi
Bladawiec
Bladawiec
 
Posty: 32
Dołączył(a): piątek, 14 listopada 2014, 17:29
Podziękował : 7
Otrzymał podziękowań: 0
System operacyjny: win 7
Kompilator: Bulider 2006
Gadu Gadu: 0
    Windows 7Firefox

Re: Sortowanie StringGrinda

Nowy postprzez Cyfrowy Baron » niedziela, 16 listopada 2014, 17:12

Nie wiem co ty kombinujesz. Ale jeśli sortujesz jedną kolumnę a w wiersze z tej kolumny są powiązane z wierszami z pozostałych kolumn to sortowanie musi uwzględniać te powiązania. To oznacza konieczność przepisania całej tabeli do jakiejś tablicy w pamięci. Potem sortujesz wybraną kolumnę a następnie każdy wiersz z posortowanej kolumny porównujesz z wierszem w tablicy z pamięci (zapamiętane powiązania) i przywracasz w pozostałych kolumnach te powiązania.

Takie sortowanie z zachowaniem powiązań opisałem w tej poradzie: http://programowanie.cal.pl/cyfbar/stringgrid.html#grid18



Boshi napisał(a):
KOD cpp:     UKRYJ  
StrToIntDef(l+p, 1) / 2
; np Ada+Zdzisiał/2 = ??? bezsens wydaje mi sie.


Wcale nie masz Ada+Zdzisław/2, gdyż funkcja StringToIntDef próbuje dokonać konwersji tekstu na liczbę, ale to się może udać tylko wtedy gdy tekst jest liczbą w innej sytuacji funkcja zwraca wartość domyślną, czyli to jest 1 / 2



Co do przeszukiwania tabeli StringGrid to masz tą poradę: http://programowanie.cal.pl/cyfbar/stringgrid.html#grid20
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows 7Firefox


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 2 gości