sortarea unor structuri in C++


  1. #1
    Senior Member Swifty_yo's Avatar Swifty_yo reprezinta o cantitate neglijabila
    Data de inscriere
    21-11-2005
    Locaţie
    Intr-o Scorbura
    Varsta
    37
    Sex
    M
    Mesaje
    774
    Mesaje bazar
    222
    Putere Reputatie
    0
    Reputatie
    9
    Puncte CF
    11.0

    sortarea unor structuri in C++

    M-am apucat de un program in C++ ce trebuie sa citeasca un fisier si sa extraga din el date referitoare la niste puncte. Adresa pe axele X si Y si diametrul punctului.
    Cand am inceput proiectul m-am gandit ca o sa trebuiasca sortate respectivele puncte si de aceea am declarat o structura de tipul:

    struct adresa{
    short int x, y, diam;
    }punct[n];

    Cand am ajuns la partea cu sortatul m-am blocat. Am cautat pe net tutoriale si instructiuni, dar nu am reusit nimic.

    Nu stiu cum sa sortez punctele la final. Mai intai in functie de diametru, apoi de adresa pe axa y si apoi de adresa pe axa x, in ordine crescatoare.

    Am incercat cu comanda "qsort", am avut ceva probleme si cand in sfarsit am facut completarile de rigoare in cod, imi da eroare compilatorul de c, ca nu poate sa citeasca o adresa de memorie. (folosesc visual c++ 6.0)

    momentan am lasat un algoritm simplu ce imi permite sortarea dupa un singur membru al structurii:

    void sort() //functia de sortare
    {
    for (i = 0; i < n1 - 1; i++)
    {
    for (j = i + 1; j < n1; j++)
    {

    if (punct[i].diam-punct[j].diam < 1)
    {
    struct adresa adrTemp;
    adrTemp.diam = punct[i].diam;
    adrTemp.x = punct[i].x;
    adrTemp.y = punct[i].y;

    punct[i].diam = punct[j].diam;
    punct[i].x = punct[j].x;
    punct[i].y = punct[j].y;

    punct[j].diam = adrTemp.diam;
    punct[j].x = adrTemp.x;
    punct[j].y = adrTemp.y;
    }

    }
    }
    }

    Puteti sa imi dati putin ajutor?

    Multumesc!
    Azi cand ai putere, aur si marire,
    prinde radacina orice fericire!
    Inaintea ta un altu-a fost stapanul lumii,
    dupa tine, altu-o va lua in stapanire.

    (Saadi)

  2. #2
    0-day Member adrian_mirea reprezinta o cantitate neglijabila
    Data de inscriere
    07-05-2010
    Sex
    M
    Mesaje
    9
    Putere Reputatie
    29
    Reputatie
    10
    Puncte CF
    0.0
    Am postat mai jos o variantă, sper să fie corectă; cel puțin la mine pare că merge. Folosesc linux, așa ca nu sunt 100% sigur că îti va merge din prima, dar sunt lucruri minore de modificat [ totuși e același limbaj, standardizat ANSI ]

    Recomand să citești codul de jos în sus, adică începând cu funcția main.
    [ nu mă refer neapărat la programul ăsta, ci era mai mult un sfat general ]

    Și încearcă în general să folosești cât mai multe funcții, nu să scrii totul într-un bloc mare de cod...

    La școală îmi aduc aminte că se făcea totul în main, cu variabile globale cât cuprinde, și denumite i, k, m, p ,t, q, r, fără tab-uri acolo unde trebuie să fie [ fără indentare corespunzătoare adică] ... Asta dăunează foarte mult lizibilitații, nu numai pentru ceilalți care citesc dar chiar și pentru programatorul care dezvoltă [ nu ziceam de codul postat de tine acum, ziceam ca sfat general, ce ai pus tu aici e destul de clar scris și bine enunțat]

    Oricum zic, intre "int ț" și "int nNumClick" de exemplu ar trebui să fie clar care e mai bună.
    La fel, între a pune totul într-o funcție și a face funcții ajutătoare unde se poate.

    Mă lungesc, scuze.

    Numai bine.


    Cod:
    #include <stdio.h>
    #include <time.h>
    #include <stdlib.h>
    #include <math.h>
    
    
    const int n = 15;  // numărul maxim de elemente
    
    struct adresa{
    short int x, y, diam;
    }punct[n];
    
    
    // funcție ajutătoare care interschimbă
    // 2 elemente ale structurii
    void interschimba(int i, int j)
    {
     int temp;
    
     // schimbă x
     temp = punct[i].x;
     punct[i].x = punct[j].x;
     punct[j].x = temp;
    
     // schimbă y
     temp = punct[i].y;
     punct[i].y = punct[j].y;
     punct[j].y = temp;
    
     // schimbă diam
     temp = punct[i].diam;
     punct[i].diam = punct[j].diam;
     punct[j].diam = temp;
    }
    
    void sort()
    {
     int gata = 0;
    
    
     while(gata==0)
     {
    	gata = 1;	
    	for(int i=0; i<n-1; i++)
    		for(int j=i+1; j<n;j++)
    		{
    			// dacă diametrul lui i e mai mare, interschimbă și marchează 
    			// faptul că am făcut ceva la iterația curentă 
    			// [ ca să nu se oprească procesul de sortare ]
    			if(punct[i].diam > punct[j].diam)
    			{
    				interschimba(i, j);
    				gata = 0;
    			}
    			// dacă au același diam, dar x-ul celui de indice mai mic(i) este mai mare decât
    			// al celui de indice j, atunci interschimbă
    			else if( (punct[i].diam == punct[j].diam) && (punct[i].x > punct[j].x) )
    			{
    				interschimba(i, j);
    				gata = 0;	
    			}
    			// dacă au același diam și același x, dar punct[i].y > punct[j].y, trebuie interschimbate
    			else if( (punct[i].diam == punct[j].diam) && (punct[i].x == punct[j].x) && (punct[i].y > punct[j].y) )
    			{
    				interschimba(i, j);
    				gata = 0;	
    			}
    		}
     }	
    }
    
    void afiseazaStructura()
    {
     for(int i=0; i<n; i++)
     {
      printf("Elementul %d: ", i);
      printf("x = %02d, y= %02d, diam= %02d\n", punct[i].x, punct[i].y, punct[i].diam);
     }
     printf("\n");
    }
    
    void initializari()
    {
     srand(time(0));
     // generează niște date aleatoare pentru structură
     for(int i=0; i<n; i++)
     {
    	if(rand()%3==0 && i>0)
    		punct[i].x = punct[i-1].x; // pune din când în când și niște coordonate x egale [ mai precis 1 din 333 ]
    	else
    		punct[i].x = rand() % 100;
    
    	
    	if(rand()%3==0 && i>0)
    		punct[i].y = punct[i-1].y; // analog  
    	else
    		punct[i].y = rand() % 100;
    
    	if(rand()%3==0 && i>0)
    		punct[i].diam = punct[i-1].diam;  // analog 
    	else
    		punct[i].diam = rand() % 100;
     }
    }
    
    int main()
    {
     initializari();
    
     afiseazaStructura();
     sort();
    
     afiseazaStructura();
    
     return 0;
    }
    Vrei mai putine reclame? Inregistreaza-te sau logheaza-te

  3. #3
    Senior Member Swifty_yo's Avatar Swifty_yo reprezinta o cantitate neglijabila
    Data de inscriere
    21-11-2005
    Locaţie
    Intr-o Scorbura
    Varsta
    37
    Sex
    M
    Mesaje
    774
    Mesaje bazar
    222
    Putere Reputatie
    0
    Reputatie
    9
    Puncte CF
    11.0
    Multumesc mult pentru ajutor. Este exact ce imi trebuie. Algoritmul dat de tine sorteaza dupa diam, apoi x, apoi y, dar o sa-l modific, pentru ca l-am inteles (mersi pt comentariile din cod) .

    Scuze ca am raspuns asa greu, dar deabia astaseara am avut timpul sa-l testez.

    Iti multumesc inca odata.
    O sa las thread-ul deschis, in caz ca o sa mai intampin si alte probleme sa mai cer ajutorul.

    Cu respect,
    Mihai!
    Azi cand ai putere, aur si marire,
    prinde radacina orice fericire!
    Inaintea ta un altu-a fost stapanul lumii,
    dupa tine, altu-o va lua in stapanire.

    (Saadi)

  4. #4
    Trance Addicted! Reaver's Avatar Reaver este o raza de lumina in ochii tuturor Reaver este o raza de lumina in ochii tuturor Reaver este o raza de lumina in ochii tuturor Reaver este o raza de lumina in ochii tuturor Reaver este o raza de lumina in ochii tuturor Reaver este o raza de lumina in ochii tuturor
    Data de inscriere
    29-09-2005
    Locaţie
    Far, far away!
    Varsta
    43
    Sex
    M
    Mesaje
    1,994
    Mesaje bazar
    226
    Putere Reputatie
    47
    Reputatie
    598
    Puncte CF
    41.0
    Usergroups:
    De ce nu folosesti STL?
    Cauta pe google documentatii despre STL. Poti pune structura aia intr-o lista, careia ii aplici un operator de sortare (less, greater), apoi suprascrii acel operator in care iti pui logica dupa care vrei sa sortezi obiectele din lista.

    Hai sa-ti dau si un exemplu, sa nu zici ca-s rau:

    Cod:
    #include <iostream>
    #include <set>
    using namespace std;
    
    struct adresa{
        short int x;
        short int y;
        short int diam;
    };
    
    struct cmp {
        bool operator()(adresa a, adresa b) const {
            if (a.diam < b.diam)
                return true;
            else if (a.diam > b.diam)
                return false;
            else {
                if (a.x < b.x)
                    return true;
                else if (a.x > b.x)
                    return false;
                else {
                    if (a.y < b.y)
                        return true;
                    else if (a.y > b.y)
                        return false;
                }
            }
            return true;
        }
    };
    
    int main() {
        set<adresa, cmp> lista_adrese;
        adresa x[5] = {{4,5,10},
                       {6,7,10},
                       {6,7,9},
                       {3,8,12},
                       {4,5,10}};
        lista_adrese.insert(x[0]);
        lista_adrese.insert(x[1]);
        lista_adrese.insert(x[2]);
        lista_adrese.insert(x[3]);
        lista_adrese.insert(x[4]);
        set<adresa, cmp>::iterator it = lista_adrese.begin();
        for (; it != lista_adrese.end(); it++) {
            cout << it->x << " " << it->y << " " << it->diam << endl;
        }
        return 0;
    }
    Simplu, scurt, C++, nu C.
    Last edited by Reaver; 19-05-2010 at 11:55. Motiv: Automerged Doublepost
    Vrei mai putine reclame? Inregistreaza-te sau logheaza-te

Google+

Cautati logo-ul CraiovaForum?

Iata cateva variante: