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

Sortowanie StringGrid

dział ogólny

Re: Sortowanie StringGrid

Nowy postprzez Cyfrowy Baron » środa, 9 lutego 2011, 22:02

Przeanalizuj kod, powiem tylko, że funkcja wykorzystuje funkcję CustomSort obiektu typu TStringList, sama funkcja SortGrid tak naprawdę niczego nie sortuje, lecz odpowiednio ustawia funkcję CustomSort.
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 XPFirefox

Re: Sortowanie StringGrid

Nowy postprzez mufasa » piątek, 11 lutego 2011, 22:00

Mniej więcej rozumiem zastanawia mnie tylko funkcja cTemp1.Pos("^") i cTemp2.Pos("^"), jakbyś mógł napisać co ona oznacza :)

Kod: Zaznacz cały
int __fastcall CustomSortDecreaseInt(TStringList *Lista, int idx1, int idx2)
{
        String cTemp1 = Lista->Strings[idx1];
        String cTemp2 = Lista->Strings[idx2];
        int x1 = cTemp1.Pos("^");
        int x2 = cTemp2.Pos("^");
        int rTemp1 = cTemp1.SubString(1, x1 - 1).Trim().ToIntDef(0);
        int rTemp2 = cTemp2.SubString(1, x2 - 1).Trim().ToIntDef(0);

        return -foo(rTemp1, rTemp2);
}


a i nigdzie nie widziałem przekazania wartości do funkcji idx1 oraz idx2 ale może to tylko moja nieuwaga, ale jeśli nie to co to są za wartości
Kod: Zaznacz cały
switch(tsSort)  //wybór sortowania
        {
                 case tsIncrease:    SortList->CustomSort(CustomSortIncrease); break;
                 case tsIncreaseInt: SortList->CustomSort(CustomSortIncreaseInt); break;
                 case tsDecrease:    SortList->CustomSort(CustomSortDecrease); break;
                 case tsDecreaseInt: SortList->CustomSort(CustomSortDecreaseInt); break;
         }
Avatar użytkownika
mufasa
Bladawiec
Bladawiec
 
Posty: 26
Dołączył(a): poniedziałek, 31 stycznia 2011, 17:36
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows XP
Kompilator: c++ builder 6 enterprise
Gadu Gadu: 0
    Windows XPFirefox

Re: Sortowanie StringGrid

Nowy postprzez Cyfrowy Baron » piątek, 11 lutego 2011, 23:25

Mniej więcej rozumiem zastanawia mnie tylko funkcja cTemp1.Pos("^") i cTemp2.Pos("^"), jakbyś mógł napisać co ona oznacza :)


W tabeli masz w jednym wierszu wiele komórek, np:

| wartość 1 | wartość 2 | wartość 3 |

Lista potrafi przechowywać tylko wiersze, więc komórki z wiersza są sumowane w wierszu listy:

wartość 1^wartość 2^wartość 3

Sam symbol ^ jest nieistotny, gdyż jest tylko separatorem. Użyłem tego symbolu, gdyż jest praktycznie nieużywany, ale to również oznacza, że w komórkach tabeli nie można użyć tego symbolu, w przeciwnym razie przepisanie danych po sortowaniu do tabeli spowoduje błędy.



a i nigdzie nie widziałem przekazania wartości do funkcji idx1 oraz idx2 ale może to tylko moja nieuwaga, ale jeśli nie to co to są za wartości


Są przekazywane poprzez funkcję CustomSort, która to funkcja nie pobiera wszak argumentów, lecz funkcję - spójrz na kod - funkcji CustomSort jako argument przekazywane są różne funkcje - tutaj cztery - które zawsze maja tą samą konstrukcję, czyli argumenty tych funkcji to typ TStringList i dwa razy po typie int. Wynika to z konstrukcji funkcji CustomSort:

KOD cpp:     UKRYJ  
virtual void __fastcall CustomSort(int (_fastcall *)(Classes::TStringList *,int,int) Compare);

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
mufasa
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 XPFirefox

Re: Sortowanie StringGrid

Nowy postprzez mufasa » sobota, 12 lutego 2011, 00:26

Dziękuje za odpowiedź

Jeszcze jedna sprawa teraz zauważyłem, Chodzi o sortowanie CustomSortDecreaseInt oraz CustomSortIncreaseInt odkąd poprawiłeś mój błąd w funkcji sortuje dobrze z tym że jeśli mamy jeszcze niewypełnione komórki to przesortowywuje je między sobą

przed sortowaniem:
Jan Kowalski 130 220
Adam Poldek 140 240
Tomasz Kot - -
Adam Adamek - -
Piotr Pichur - -

po pierwszym sortowaniu:

Adam Poldek 140 240
Jan Kowalski 130 220
Piotr Pichur - -
Adam Adamek - -
Tomasz Kot - -

po drugim:

Adam Poldek 140 240
Jan Kowalski 130 220
Tomasz Kot - -
Piotr Pichur - -
Adam Adamek - -

czyli tak jakby sortuje komórki w których jeszcze niema wartości, jest na to jakiś sposób aby tego nie robił?
Avatar użytkownika
mufasa
Bladawiec
Bladawiec
 
Posty: 26
Dołączył(a): poniedziałek, 31 stycznia 2011, 17:36
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows XP
Kompilator: c++ builder 6 enterprise
Gadu Gadu: 0
    Windows XPFirefox

Re: Sortowanie StringGrid

Nowy postprzez Cyfrowy Baron » sobota, 12 lutego 2011, 09:49

Komórki nie powinny pozostawać puste tam gdzie stosujesz sortowanie wg. liczb. Należałoby je wypełnić wartością domyślną np. 0.
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 XPFirefox

Re: Sortowanie StringGrid

Nowy postprzez mufasa » sobota, 12 lutego 2011, 12:23

Zrobiłem to tak, żeby nie zajmował się komórkami pustymi
Kod: Zaznacz cały
  for(int i = Grid->FixedRows; i < Grid->RowCount; i++)
        {
                temp = Grid->Cells[Col][i];
              if(!temp.IsEmpty())
                {
                for(int z = Grid->FixedCols; z <= Grid->ColCount; z++)
                {
                        if(Grid->Cells[z][i].IsEmpty()) Grid->Cells[z][i] = " ";  //jesli komorka jest pusta dodaj biały znak
                         if(z != Col)      //jesli z jest różne od kolumny po której sortujemy
                                 temp = temp + "^" + Grid->Cells[z][i]; //Dodanie separatora ^ pomiędzy komórkami

                 }
                 SortList->Add(temp.SubString(0, temp.Length() - 1));  //Tworzenie listy do sortowanis
                temp = "";   //wyczyszczenie temp
                }
        }
Avatar użytkownika
mufasa
Bladawiec
Bladawiec
 
Posty: 26
Dołączył(a): poniedziałek, 31 stycznia 2011, 17:36
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows XP
Kompilator: c++ builder 6 enterprise
Gadu Gadu: 0
    Windows XPFirefox

Re: Sortowanie StringGrid

Nowy postprzez Cyfrowy Baron » sobota, 12 lutego 2011, 15:00

A nie lepiej było na potrzeby sortowania wypełniać puste komórki wartością 0. Pomijając puste komórki przy sortowaniu wg. liczb, gdy komórka nie zawiera liczby wciąż może pojawić się błąd:

KOD cpp:     UKRYJ  
for(int i = Grid->FixedRows; i < Grid->RowCount; i++)
{
    for(int z = Grid->FixedCols; z <= Grid->ColCount; z++)
    {
      if(Grid->Cells[z][i].IsEmpty()) Grid->Cells[z][i] = "0"; /* tutaj wartość domyślna  zamiast spacji */
      if(z != Col)  temp = temp + "^" + Grid->Cells[z][i];

    }
    SortList->Add(temp.SubString(0, temp.Length() - 1));  //Tworzenie listy do sortowanis
    temp = "";   //wyczyszczenie temp
}


Zauważ, że kod zawierał już odpowiednie rozwiązanie, lecz zamiast zera wstawiał spację:

KOD cpp:     UKRYJ  
if(Grid->Cells[z][i].IsEmpty()) Grid->Cells[z][i] = " "; //jesli komorka jest pusta dodaj biały znak


Nawet było to opisane i wystarczyło tutaj zmienić:

KOD cpp:     UKRYJ  
if(Grid->Cells[z][i].IsEmpty()) Grid->Cells[z][i] = "0";


Nie rozumiesz kodu. Przepisujesz go bez zrozumienia i nie analizujesz stąd takie kombinacje. Z Twoim rozwiązaniem tej kod if(Grid->Cells[z][i].IsEmpty()) Grid->Cells[z][i] = " "; //jesli komorka jest pusta dodaj biały znak jest zbędny, gdyż warunek nigdy nie zostanie spełniony.



Zamiast tagów CODE używaj dla kodu tagów CPP
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 XPFirefox

Re: Sortowanie StringGrid

Nowy postprzez mufasa » sobota, 12 lutego 2011, 15:21

Cyfrowy Baron napisał(a):
Zauważ, że kod zawierał już odpowiednie rozwiązanie, lecz zamiast zera wstawiał spację:

KOD cpp:     UKRYJ  
if(Grid->Cells[z][i].IsEmpty()) Grid->Cells[z][i] = " "; //jesli komorka jest pusta dodaj biały znak


Nawet było to opisane i wystarczyło tutaj zmienić:

KOD cpp:     UKRYJ  
if(Grid->Cells[z][i].IsEmpty()) Grid->Cells[z][i] = "0";




Tak też wcześniej testowałem, ale z tym rozwiązaniem dzieje się tak samo wszystkie komórki mają tą samą wartość czyli '0' więc je przetasowywuje również między sobą
Avatar użytkownika
mufasa
Bladawiec
Bladawiec
 
Posty: 26
Dołączył(a): poniedziałek, 31 stycznia 2011, 17:36
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows XP
Kompilator: c++ builder 6 enterprise
Gadu Gadu: 0
    Windows XPFirefox

Re: Sortowanie StringGrid

Nowy postprzez Cyfrowy Baron » sobota, 12 lutego 2011, 16:06

To całe przetasowanie dotyczy sytuacji w której sortujesz tabelę wg. liczb, a skoro wiersze liczb nie zawierają to tasowanie tych wierszy jest bez znaczenia.
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 XPFirefox

Re: Sortowanie StringGrid

Nowy postprzez mufasa » sobota, 12 lutego 2011, 16:38

Z tym rozwiązaniem jest cały czas ta sytuacja która przedstawiłem kilka postów temu:

przed sortowaniem:
Jan Kowalski 130 220
Adam Poldek 140 240
Tomasz Kot 0 0
Adam Adamek 0 0
Piotr Pichur 0 0

po pierwszym sortowaniu:

Adam Poldek 140 240
Jan Kowalski 130 220
Piotr Pichur 0 0
Adam Adamek 0 0
Tomasz Kot 0 0

po drugim:

Adam Poldek 140 240
Jan Kowalski 130 220
Tomasz Kot 0 0
Piotr Pichur 0 0
Adam Adamek 0 0
Avatar użytkownika
mufasa
Bladawiec
Bladawiec
 
Posty: 26
Dołączył(a): poniedziałek, 31 stycznia 2011, 17:36
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows XP
Kompilator: c++ builder 6 enterprise
Gadu Gadu: 0
    Windows XPFirefox

Re: Sortowanie StringGrid

Nowy postprzez Cyfrowy Baron » sobota, 12 lutego 2011, 16:45

Nie jest to ta sama sytuacja co wcześniej, gdyż teraz powiązania nie są gubione. Jeżeli wybierasz swoje rozwiązanie, to usuń z pętli tą linię:

KOD cpp:     UKRYJ  
if(Grid->Cells[z][i].IsEmpty()) Grid->Cells[z][i] = " ";


Jest niepotrzebna, gdyż warunek nigdy nie będzie spełniony.
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 XPFirefox

Re: Sortowanie StringGrid

Nowy postprzez mufasa » czwartek, 17 lutego 2011, 21:02

Kod: Zaznacz cały
        switch(tsSort)  //wybór sortowania
        {
                 case tsIncrease:    SortList->CustomSort(CustomSortIncrease); break;
                 case tsIncreaseInt: SortList->CustomSort(CustomSortIncreaseInt); break;
                 case tsDecrease:    SortList->CustomSort(CustomSortDecrease); break;
                 case tsDecreaseInt: SortList->CustomSort(CustomSortDecreaseInt); break;
         }


Kod: Zaznacz cały
int __fastcall CustomSortDecreaseInt(TStringList *Lista, int idx1, int idx2)
{
        String cTemp1 = Lista->Strings[idx1];
        String cTemp2 = Lista->Strings[idx2];
        int x1 = cTemp1.Pos("^");    //pozycja separatora
        int x2 = cTemp2.Pos("^");    //pozycja separatora
        int rTemp1 = cTemp1.SubString(1, x1 - 1).Trim().ToIntDef(0);//wyciągamy wartosc z Listy usuwamy białe znaki i zamieniamy na int
        int rTemp2 = cTemp2.SubString(1, x2 - 1).Trim().ToIntDef(0);

        return -foo(rTemp1, rTemp2);
}


Kod: Zaznacz cały
int foo(int u, int i)  /* funkcja pomocnicza */
{
        int z = u - i;
        return z;
}


Mógłbyś mi powiedzieć do czego jest nam potrzebna funkcja pomocnicza 'foo' skoro sortowanie odbywa się przez metodę 'CustomSort' .
a i gdzie jest zwracana posortowana lista?
Avatar użytkownika
mufasa
Bladawiec
Bladawiec
 
Posty: 26
Dołączył(a): poniedziałek, 31 stycznia 2011, 17:36
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows XP
Kompilator: c++ builder 6 enterprise
Gadu Gadu: 0
    Windows XPFirefox

Re: Sortowanie StringGrid

Nowy postprzez Cyfrowy Baron » czwartek, 17 lutego 2011, 21:15

foo potrzebna jest do sortowania wg. liczb. Jak widzisz funkcja ta jest wykorzystywana w funkcjach CustomSortDecreaseInt i CustomSortIncreaseInt.

KOD cpp:     UKRYJ  
int __fastcall CustomSortDecreaseInt(TStringList *Lista, int idx1, int idx2)
{
        String cTemp1 = Lista->Strings[idx1];
        String cTemp2 = Lista->Strings[idx2];
        int x1 = cTemp1.Pos("^");    //pozycja separatora
        int x2 = cTemp2.Pos("^");    //pozycja separatora
        int rTemp1 = cTemp1.SubString(1, x1 - 1).Trim().ToIntDef(0);//wyciągamy wartosc z Listy usuwamy białe znaki i zamieniamy na int
        int rTemp2 = cTemp2.SubString(1, x2 - 1).Trim().ToIntDef(0);

        return -foo(rTemp1, rTemp2);  // <-- PATRZ TUTAJ
}
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 XPFirefox

Re: Sortowanie StringGrid

Nowy postprzez polymorphism » czwartek, 17 lutego 2011, 21:32

A nie można po prostu:
KOD cpp:     UKRYJ  
return rTemp2 - rTemp1;

bez foo :?:
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Sortowanie StringGrid

Nowy postprzez mufasa » piątek, 18 lutego 2011, 02:30

foo potrzebna jest do sortowania wg. liczb. Jak widzisz funkcja ta jest wykorzystywana w funkcjach CustomSortDecreaseInt i CustomSortIncreaseInt.


Bardziej mi chodziło o to co nam ta funkcja daje bo to, że odejmuje jedną wartość od drugiej i zwraca wynik to wiem. Tylko co nam daje ten wynik, jak on jest póżniej wykorzystywany w celu sortowania.
Avatar użytkownika
mufasa
Bladawiec
Bladawiec
 
Posty: 26
Dołączył(a): poniedziałek, 31 stycznia 2011, 17:36
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows XP
Kompilator: c++ builder 6 enterprise
Gadu Gadu: 0
    MacintoshSafari

Poprzednia stronaNastępna strona

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 5 gości