Strings sortieren lassen mit qsort



  • Hi,
    wir haben die Aufgabe bekommen Zeichenketten zu sortieren unter anderem auch mit qsort allerdings geht das nicht wirklich 😉

    Was ist falsch bzw. wie kann ich Strings mittels der qsort sorieren (bzw. mit einem in C++ vorhandenem Quicksort)

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int compare(const void * a, const void * b){
    
    			string a1 = *((string*)a);
    
     		 	string b1 = *((string*)b);
    
    			if(a1 < b1) return 1;
    			if(a1 > b1) return -1;	
    			if(a1 == b1) return 0;
    		}
    
    int main(){
    	string bla[9];
    	bla[0] = "v1";
    	bla[1] = "a1";
    	bla[2] = "a7";
    	bla[3] = "zz";
    	bla[4] = "zu";
    	bla[5] = "6h";
    	bla[6] = "k1";
    	bla[7] = "uu";
    	bla[8] = "ah";
    	bla[9] = "hh";
    	qsort (bla, 10, sizeof(string), compare);
    
    	return 0;
    }
    


  • wenn du dein array 10 elemente groß machst (du verwendest ja auch 10 strings) dann gehts. dann drehst noch die vorzeichen in deiner comparemethode um und der sortiert dir das supi aufsteigend alphabethisch. 🙂



  • Erstens: qsort() ist eine C-Funktion und arbeitet nicht besonders gut mit C++ Objekten zusammen (ausführlicher: Es umgeht beim Umsortieren des Arrays alle wichtigen Methoden der String-Klasse - und kann dir damit deine Daten komplett pulverisieren). In C++ verwendet man sort(), stable_sort() oder partial_sort() (die unterscheiden sich vor allem in Detail-Fragen - sort() arbeitet idR mit QuickSort).

    Zweitens: In einem 'string bla[9];' gibt es kein Element 'bla[9]'.



  • Aufruf in der main.cpp:

    libqsort obj_libqsort;
    	obj_libqsort.sorte( );
    

    Meine libqsort.h:

    class libqsort {
    
    private:
                  int ticksAnz;
                  int vglAnz; 
    
    public:
    		libqsort();
    
    		int compare(const void * a, const void * b);
    
                    int sorte ();
    
                    int getTicks();
                    int getVgl();
    };
    

    Meine libqsort.cpp:

    #include <string>
    #include <cstdlib>
    #include <iostream>
    #include "libqsort.h"
    
    using namespace std;
    
    libqsort::libqsort(){
    	ticksAnz=0;
    	vglAnz=0; 
    }
    
    int libqsort::compare(const void * a, const void * b){
    
                string a1 = *((string*)a);
    
                  string b1 = *((string*)b);
    
                if(a1 < b1) return 1;
                if(a1 > b1) return -1;   
                if(a1 == b1) return 0;
            } 
    
    int libqsort::sorte(){
    	string bla[10];
    	bla[0] = "v1";
    	bla[1] = "a1";
    	bla[2] = "a7";
    	bla[3] = "zz";
    	bla[4] = "zu";
    	bla[5] = "6h";
    	bla[6] = "k1j";
    	bla[7] = "uu";
    	bla[8] = "ah";
    	bla[9] = "hh";
    	qsort (bla, 10, sizeof(string), compare);
    
    	for(int i = 0; i < 10; i++){
    		cout << bla[i] << endl;
    	}
    	return 0;
    }
    
    int libqsort::getTicks() { return ticksAnz; }
    int libqsort::getVgl()   { return vglAnz;   }
    

    Meine Fehlermeldung:

    g++ -c libqsort.cpp
    libqsort.cpp: In member function ‘int libqsort::sorte()’:
    libqsort.cpp:37: error: argument of type ‘int (libqsort::)(const void*, const void*)’ does not match ‘int ()(const void, const void*)’
    make: *** [libqsort.o] Error 1

    Zusatzinfos:
    Kompilieren tu ich mit dem g++ und das Beispiel von oben klappt mit euren Tipps ohne Probleme.

    Frage:
    Was ist daran falsch?



  • Erstens: Du kannst nur globale Funktionen und statische Methoden als Funktionszeiger herumreichen. "Normale" Methoden kannst du nur als Methodenzeiger weitergeben, aber mit denen kann qsort() nichts anfangen.

    Zweitens: Versuch besser nicht, C++ Objekte mit C Funktionen zu bearbeiten. C hat keine Ahnung von Konstruktoren, Zuweisungsoperatoren und änhlichen Konzepten, also besteht die Gefahr, daß es dir deine Strings klammheimlich in Stücke schlägt. Nimm besser std::sort() (da brauchst du nicht einmal eine Hilfsfunktion wie 'compare()', um zwei Strings zu vergleichen ;)).



  • Ich habs jetzt verändert:

    Teil der cpp Datei:

    bool libqsort::compare(std::string string1, std::string string2)
    {
        	if(string1 > string2)return false;
    	else return true;
    }
    
    int libqsort::sort(std::vector<std::string> SortString){
    	std::sort(SortString.begin(),SortString.end(), libqsort::compare);
    
    	for( int i = 0, limit = SortString.size(); i < limit; ++i )
    	{
    		std::cout << SortString[ i ].c_str() << std::endl;
    	}
    	return 0;
    }
    

    in der h datei:

    bool compare(std::string, std::string);
    

    Jetzt habe ich diese Fehlermeldung (gekürzt):

    g++ -c libqsort.cpp
    /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h: In function ‘void std::partial_sort(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, _Compare = bool (libqsort::)(std::string, std::string)]’:
    /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:2666: instantiated from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, _Size = int, _Compare = bool (libqsort::)(std::string, std::string)]’
    /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:2749: instantiated from ‘void std::sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, _Compare = bool (libqsort::)(std::string, std::string)]’
    libqsort.cpp:21: instantiated from here
    /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:2477: error: must use ‘.’ or ‘->’ to call pointer-to-member function in ‘__comp (...)’

    So jetzt das Problem: Wenn ich die Compare Funktion Global habe gehts in der Klasse allerdings nicht. Leider brauche ich die um die Anzahl der Vergleiche zu bekommen.

    vielen Dank
    wdsl



  • Wenn du es unbedingt in der Klasse haben willst, setz' mal ein 'static' vor die Methode (auch std::sort() tut sich schwer mit Methodenzeigern - weil es nicht weiß, was es als 'this' übergeben soll).


Anmelden zum Antworten