Sortowanie bąbelkowe elementow char*

0

Jako że to jest mój pierwszy post na forum witam wszystkich.

Mam funkcję w której wczytuję 6 łańcuchów, łańcuchy przechowywane są w tablicy wskaźników do nich.
Chciałbym je posortować w kolejności alfabetycznej, tak żeby nie tracić pierwowzoru kolejności. Próbowałem to zrobić za pomocą sortowania bąbelkowego. Kod się kompiluje jednak nie uzyskuję rezultatu takiego jaki bym oczekiwał.
Szerze domyślam się że popełniłem w nim jakieś straszne błędy, może ktoś mi je wskaże? Próbowałem to sam rozgryźć ale tak się pogubiłem, że już nie mam sił do tego kodu. [glowa]
Zaznaczyłem fragment z którym jest coś nie tak:

//       FUN 4
void fun4()
{   
    cout<<"Podaj 6 lancuchow: "<<endl;
    char tablica1[100],tablica2[100],tablica3[100],tablica4[100],tablica5[100],tablica6[100];
    char *tab_wsk[6]={tablica1,tablica2,tablica3,tablica4,tablica5,tablica6};
                              for(int i=0 ; i<6 ; i++)
                              {       
                                      cout<<"Podaj lancuch nr "<<i+1<<": ";
                                      
                                      gets(tab_wsk[i]);
                                      
                                     
                              }
    int koniec=1;
    do
    {
            cout<<"Wybierz opcje:\n";
            cout<<"1) Wyswietl pierwotną liste lancuchow\n"
                <<"2) Wyswietl lancuchy w porzadku ASCII\n"
                <<"3) Wyswietl lancuchy wg dlugosci\n"
                <<"4) Koniec"<<endl;
            cout<<"Podaj numer: ";
    int numer;
    cin>>numer;
    cin.ignore();
                
                 switch(numer)
                 {
                 case 1:
                       { 
                              for(int i=0 ; i<6 ; i++)
                              {       
                                      cout<<"Lancuch nr "<<i+1<<": ";
                                      cout<<(tab_wsk[i]);
                                      cout<<"\n";
                                     
                              }
                       }
                      break;
                 case 2:
                      //Kopiowanie wskaźników tablic do nowej tablicy wskaźników
                      {
                            char *tab_wsk_copy[6];
                            for(int i = 0; i < 6 ; i++)
                            {
                                  tab_wsk_copy[i]=tab_wsk[i];
                                  cout<<tab_wsk_copy[i]+2;
                            }
                      //Sortowanie bąbelkowe nowej tablicy wskaźników w porządku ASCII
                      
                      // Gdzie jest błąd?
                      
                      for(int i=1 ; i < 6 ; i++)
                              for(int j = 5 ; j >=i ; j --)
                              {        
                                      //Pętla porównująca pierwsze znaki, jeśli są takie 
                                      //same porównywane są kolejne
                                      int k=1;   //domyślam się, że tu także jest błąd, ale zgubiłem się przez miejsce                                         // w którym przypisuję wartości
                                      while(tab_wsk_copy[j-1][k-1]==tab_wsk_copy[j][k-1])
                                      {
                                      if(tab_wsk_copy[j-1][k]> tab_wsk_copy[j][k])
                                                               {
                                                                   char *tab_pom;  
                                                                   tab_pom=tab_wsk_copy[j-1];// to miejsce mnie zastanawia
                                                                   tab_wsk_copy[j-1]=tab_wsk_copy[j];
                                                                   tab_wsk_copy[j-1]=tab_pom;
                                                               }
                                      k++;
                                      }
                              
                      //Gdzie jest błąd? [koniec]
                                     
                              }
                              //Do wyświetlania wyników (umieścić w funkcji)
                              for(int i=0 ; i<6 ; i++)
                              {       
                                      cout<<"Lancuch nr "<<i+1<<": ";
                                      cout<<(tab_wsk_copy[i]);
                                      cout<<"\n";
                                     
                              }
                      
                      
                            
                      }
                      break;
                 case 3:
                      {
                      }
                      break;
                 case 4:
                      {
                            koniec=0;
                      }
                      break;
                 }
    }
    while(koniec);
    
}    
</cpp>
0

Użyj funkcji strcmp i posortuj jak normalne liczby, to się nie pogubisz.

0

nie bardzo rozumiem dlaczego mam użyć strcmp(), porównywanie stosuję tylko do znaków w łańcuchach które się różnią. One wtedy decydują o tym który łańcuch ma pierwszeństwo jeśli chodzi o porządek alfabetyczny. Mój problem głównie sprowadza się do podmienienia łańcuchów (w jakiej zmiennej pomocniczej powinny być przechowywane). Z sortowaniem sobie jakoś poradzę, gdy będę widział jakikolwiek rezultat, na razie mi po prostu wyświetla łańcuchy w takiej samej kolejności.

0

Jasne, wymyślaj kolejny raz koło! strcmp(); strcpy(); to wszystko czego ci potrzeba.
Robisz bufor char bufor[100];
Wybierasz dwa wyrazy, robisz strcmp(pierwszy,drugi); jeśli są w złej kolejności to robisz

strcpy(bufor,pierwszy);
strcpy(pierwszy,drugi);
strcpy(drugi,bufor);
0

Dzięki wielkie za radę, teraz kod jest czytelny i co najważniejsze działa.

0

mam jeszcze pytanie czemu nie można napisać tak:

strcpy(tab_wsk_copy,tab_wsk);

Wyświetla mi błąd:

cannot convert 'char**' to 'char*' for argument '1' to 'char * strcpy(char*,const char*)'

Wszystko działało po poprawkach tak jak powinno poza tym że case 1: powinien zwracać mi łańcuchy w oryginalnej kolejności, a tak nie robi :/

0

To moze z laski swojej wklej kod po poprawkach? ;)
tab_wsk_copy to jak mniemam TABLICA do wskaźników do char? Czyli TABLICA wyrazów? A strcpy() kopiuje wyrazy a nie tablice wyrazów ;]
Jeśli skopiować konkretny wyraz z tej tablicy to moze z łaski swojej wskażesz który:
strcpy(tablica[5],lalal);

0

Sorki, już wklejam kod:

//       FUN 4
void fun4()
{   
    cout<<"Podaj 6 lancuchow: "<<endl;
    char tablica1[100],tablica2[100],tablica3[100],tablica4[100],tablica5[100],tablica6[100];
    char *tab_wsk[6]={tablica1,tablica2,tablica3,tablica4,tablica5,tablica6};
                              for(int i=0 ; i<6 ; i++)
                              {       
                                      cout<<"Podaj lancuch nr "<<i+1<<": ";
                                      
                                      gets(tab_wsk[i]);
                                      
                                     
                              }
    int koniec=1;
    do
    {       
            cout<<endl;
            cout<<"----------------------------------------"<<endl;
            cout<<"Wybierz opcje:\n";
            cout<<"1) Wyswietl pierwotną liste lancuchow\n"
                <<"2) Wyswietl lancuchy w porzadku ASCII\n"
                <<"3) Wyswietl lancuchy wg dlugosci\n"
                <<"4) Koniec"<<endl;
            cout<<"----------------------------------------"<<endl;
            cout<<"Podaj numer: ";
    int numer;
    cin>>numer;
    cin.ignore();
                
                 switch(numer)
                 {
                 case 1:
                       { 
                              for(int i=0 ; i<6 ; i++)
                              {       
                                      cout<<"Lancuch nr "<<i+1<<": ";
                                      cout<<(tab_wsk[i]);
                                      cout<<"\n";
                               }
                       }
                      break;
                 case 2:
                      //Kopiowanie wskaźników tablic do nowej tablicy wskaźników
                      {
                            char *tab_wsk_copy[6];
                            for(int i = 0; i < 6 ; i++)
                            {
                                  tab_wsk_copy[i]=tab_wsk[i];
                            }
                      //Sortowanie bąbelkowe nowej tablicy wskaźników w porządku ASCII
                      for(int i=1 ; i < 6 ; i++)
                              for(int j = 5 ; j >=i ; j --)
                              {        
                                  if(strcmp(tab_wsk_copy[j-1],tab_wsk_copy[j])>0)
                                      {
                                       char bufor[100];
                                       strcpy(bufor,tab_wsk_copy[j-1]);
                                       strcpy(tab_wsk_copy[j-1],tab_wsk_copy[j]);
                                       strcpy(tab_wsk_copy[j],bufor);
                                      } 
                                   
                              }
                              //Do wyświetlania wyników (umieścić w funkcji)
                              for(int i=0 ; i<6 ; i++)
                              {       
                                      cout<<"Lancuch nr "<<i+1<<": ";
                                      cout<<(tab_wsk_copy[i]);
                                      cout<<"\n";
                                     
                              }    
                      }
                      break;
                 case 3:
                      {
                            char *tab_wsk_copy[6];
                          //  strcpy(tab_wsk_copy,tab_wsk);
                            for(int i = 0; i < 6 ; i++)
                            {     
                                  tab_wsk_copy[i]=tab_wsk[i];
                            }
                            
                            
                            
                            //Sortowanie bąbelkowe według długości
                            for(int i=1 ; i < 6 ; i++)
                              for(int j = 5 ; j >=i ; j --)
                              {
                                      if(strlen(tab_wsk_copy[j-1])>strlen(tab_wsk_copy[j])) 
                                      {        
                                       char bufor[100];
                                       strcpy(bufor,tab_wsk_copy[j-1]);
                                       strcpy(tab_wsk_copy[j-1],tab_wsk_copy[j]);
                                       strcpy(tab_wsk_copy[j],bufor);
                                       }
                              }
                              //Do wyświetlania wyników (umieścić w funkcji)
                              for(int i=0 ; i<6 ; i++)
                              {       
                                      cout<<"Lancuch nr "<<i+1<<": ";
                                      cout<<(tab_wsk_copy[i]);
                                      cout<<"\n";
                                     
                              }    
                      }
                      break;
                 case 4:
                      {
                            koniec=0;
                      }
                      break;
                 }
    }
    while(koniec);
    
}    
</cpp>
0

poprawiłem też:

tab_wsk_copy[i]=tab_wsk[i];

rzeczywiście ładniej wygląda tak:

strcpy(tab_wsk_copy[i],tab_wsk[i]);
0
void fun4()
{
  cout<<"Podaj 6 lancuchow: "<<endl;
  char tab_wsk[6][100];
  for (int i=0 ; i<6 ; i++)
    {
      cout<<"Podaj lancuch nr "<<i+1<<": ";
      gets(tab_wsk[i]);
    }
  int koniec=1;
  do
    {
      cout<<endl;
      cout<<"----------------------------------------\n"
      <<"Wybierz opcje:\n"
      <<"1) Wyswietl pierwotną liste lancuchow\n"
      <<"2) Wyswietl lancuchy w porzadku ASCII\n"
      <<"3) Wyswietl lancuchy wg dlugosci\n"
      <<"4) Koniec\n"
      <<"----------------------------------------\n"
      <<"Podaj numer: "<<endl;
      int numer;
      cin>>numer;
      cin.ignore();
      switch (numer)
        {
        case 1:
        {
          for (int i=0 ; i<6 ; i++)
            cout<<"Lancuch nr "<<i+1<<": "<<(tab_wsk[i])<<"\n";
        }
        break;
        case 2:
          //Kopiowanie wskaźników tablic do nowej tablicy wskaźników
        {
          char tab_wsk_copy[6][100]; //TUTAJ!!!!!!!!!!!!!!!!!
          for (int i = 0; i < 6 ; i++)
            strcpy(tab_wsk_copy[i],tab_wsk[i]); //I TUTAJ!!!!!!!!!!!!!
          //Sortowanie bąbelkowe nowej tablicy wskaźników w porządku ASCII
          for (int i=1 ; i < 6 ; i++)
            for (int j = 5 ; j >=i ; j --)
              {
                if (strcmp(tab_wsk_copy[j-1],tab_wsk_copy[j])>0)
                  {
                    char bufor[100];
                    strcpy(bufor,tab_wsk_copy[j-1]);
                    strcpy(tab_wsk_copy[j-1],tab_wsk_copy[j]);
                    strcpy(tab_wsk_copy[j],bufor);
                  }
              }
          //Do wyświetlania wyników (umieścić w funkcji)
          for (int i=0 ; i<6 ; i++)
            cout<<"Lancuch nr "<<i+1<<": "<<(tab_wsk_copy[i])<<"\n";
        }
        break;
        case 3:
        {
          char tab_wsk_copy[6][100]; //TUTAJ!!!!!!!!!!!!!!
          for (int i = 0; i < 6 ; i++)
            strcpy(tab_wsk_copy[i],tab_wsk[i]); //TUTAJ!!!!!!!!!!!!
          //Sortowanie bąbelkowe według długości
          for (int i=1 ; i < 6 ; i++)
            for (int j = 5 ; j >=i ; j--)
                if (strlen(tab_wsk_copy[j-1])>strlen(tab_wsk_copy[j]))
                  {
                    char bufor[100];
                    strcpy(bufor,tab_wsk_copy[j-1]);
                    strcpy(tab_wsk_copy[j-1],tab_wsk_copy[j]);
                    strcpy(tab_wsk_copy[j],bufor);
                  }
          //Do wyświetlania wyników (umieścić w funkcji)
          for (int i=0 ; i<6 ; i++)
            cout<<"Lancuch nr "<<i+1<<": "<<(tab_wsk_copy[i])<<"\n";
        }
        break;
        case 4:
        {
          koniec=0;
        }
        break;
        }
    }
  while (koniec);
}
  1. Naucz się formatowac kod...
  2. Dekompozycja! Powtarzajace sie fragmenty kodu do osobnych funkcji (np. zamiana 2 elementów)
  3. Poczytaj o wskaźnikach bo to co ty tak wyprawiasz:
 char *tab_wsk_copy[6];
 for(int i = 0; i < 6 ; i++)
   tab_wsk_copy[i]=tab_wsk[i];

Woła o pomstę do nieba! Zdajesz sobie sprawe co tutaj robisz? Przypisujesz wskaźnikom tablicy tab_wsk_copy TE SAME ADRESY jakie maja elementy tablicy głownej. Jeśli coś zmienisz pod tym adresem TO ZMIENI SIĘ WSZĘDZIE!

Jeśli 2 wskaźniki pokazuja na to samo miejsce w pamięci to zmiana wskazywanej wartości przez którykolwiek z nich powoduje zmianę dla obu!</cpp>

0

dzięki za poprawienie, po case 1: przeszedłem do case 2: bo na początku nie było widać rezultatu błędu. Potem się namotałem w nim i już jakoś ciężko mi było odnaleźć błąd wcześniej. Dzięki wielkie, a wytłumaczenie:

Jeśli 2 wskaźniki pokazują na to samo miejsce w pamięci to zmiana wskazywanej wartości przez którykolwiek z nich powoduje zmianę dla obu!

oczywiście czytałem o nim, no ale teraz już je poznałem na przykładzie i będę pamiętał. :-P

1 użytkowników online, w tym zalogowanych: 0, gości: 1