Algorithmus gesucht ...



  • Ich hab Dein Skript ma angepastt und er sagt bei "auto is_2" "expect a Class oder namespace"

    // erstes Element:
            auto first = prufzahlen.lower_bound(10); // "eins hinter das letzte Element"
            auto last  = prufzahlen.lower_bound(20); // ob es 2 sind?
            auto is_2 = [](const prufzahlen::value_type& p){return p.second=2; };
    
            // das eigentliche zaehlen:
            auto n = count_if(last= 2);
            cout << n << endl;
    


  • Sonne55 schrieb:

    Ich hab Dein Skript ma angepastt und er sagt bei "auto is_2" "expect a Class oder namespace"

    // erstes Element:
            auto first = prufzahlen.lower_bound(10); // "eins hinter das letzte Element"
            auto last  = prufzahlen.lower_bound(20); // ob es 2 sind?
            auto is_2 = [](const prufzahlen::value_type& p){return p.second=2; };
            
            // das eigentliche zaehlen:
            auto n = count_if(last= 2);
            cout << n << endl;
    

    Ich habe mitlerweile Deinen anderen Thread gesehen und gehe davon aus, dass prufzahlen in Z. 4 oben eine variable und kein Typ ist.
    Der Typ ist std::map<int,int> .

    Also wäre korrekt:

    auto is_2 = [](const std::map<int,int>::value_type& p){return p.second==2; }; // noch ein Typo gefixt...
    

    In meinem Beispiel hatte ich mit

    using map_t = std::map<int,int>;
    

    einen eigenen Namen für Diesen Typ eingeführt.

    Wir sprechen übrigens nicht von "Skript" sondern einfach von Programm oder Quellcode.



  • Furble Wurble schrieb:

    Ich habe mitlerweile Deinen anderen Thread gesehen und gehe davon aus, dass prufzahlen in Z. 4 oben eine variable und kein Typ ist.
    Der Typ ist std::map<int,int> .

    Danke

    Furble Wurble schrieb:

    Also wäre korrekt:

    auto is_2 = [](const std::map<int,int>::value_type& p){return p.second==2; }; // noch ein Typo gefixt...
    

    In meinem Beispiel hatte ich mit

    using map_t = std::map<int,int>;
    

    einen eigenen Namen für Diesen Typ eingeführt.

    Aha ...

    bei mir sagt er jetze: "Unused variable "is_2" " Ist wirklich ungewöhnlich ...

    Ich hätte ja auch bei Deiner foo-bar-Lösung bleiben können und mit Pz Vf ersetzen, aber mit denen kann man nicht rechnen, denn ich habe doch als Typ nicht umsonst int genommen.



  • Furble Wurble schrieb:

    Also wäre korrekt:

    auto is_2 = [](const std::map<int,int>::value_type& p){return p.second==2; }; // noch ein Typo gefixt...
    

    Oder wenn dein Compiler schon C++14 (generic lambdas) unterstützt kannst du dort auch auto nutzen:

    auto is_2 = [](const auto& p){return p.second==2; };
    

    Sonne55 schrieb:

    bei mir sagt er jetze: "Unused variable "is_2" " Ist wirklich ungewöhnlich ...

    Das heißt dann das du is_2 (noch) nicht benutzt hast und ist natürlich nur eine Warnung. Das is_2 Objekt brauchst du ja dann für die count_if Funktion und dann sollte auch die Warnung weg sein. Der Code

    auto n = count_if(last= 2);
    

    ist auch falsch. Mache es so wie im Beispiel von Furble Wurble nur mit is_2 , statt is_foo .



  • okay ... jetzt gibt er einen 0 aus ...

    Was ich nicht versteh:

    auto n = count_if(first, last, is_2);
    

    Er soll doch nur in "last" suchen, wieviele 2-en er dort findet. Warum kommt in die Klammer das first rein? In "first" stehen doch nur die PZ drin, und nicht eine einzige 2.

    Sind die Klammerangaben denn nicht,
    a - wo er suchen soll
    b - was er suchen soll?



  • sebi707 schrieb:

    Oder wenn dein Compiler schon C++14 (generic lambdas) unterstützt kannst du dort auch auto nutzen:

    auto is_2 = [](const auto& p){return p.second==2; };
    

    ... habe übrigens yosemite Xcode 6.1.1 ist das schon 14, oder noch 11?



  • Die Variable last ist nur ein Iterator auf ein Element (oder auch gar keins) und nicht mehrere. Du willst aber mehrere Elemente testen und genau das macht count_if . Es durchsucht alle Elemente zwischen first und last ( last nicht mit eingeschlossen). Der dritte Parameter ist dann was überhaupt gesucht wird. In deinem Fall ist das eine Lambda Funktion die prüft ob der Wert gleich 2 ist und den Key unberücksichtigt lässt.

    Sonne55 schrieb:

    ... habe übrigens yosemite Xcode 6.1.1 ist das schon 14, oder noch 11?

    Keine Ahnung. Probier doch einfach aus obs compiliert.



  • Danke, ich dachte fälschlicherweise first und last sind die beiden einanderzugeordnteten int von map.

    Jetzt müssten wir nur noch klären, warum er nicht zählt sondern imer eine Null ausgibt.... ich will nämlich in einem weiteren Schritt first und last noch dynamisieren. Kann ich mit denen rechnen? Drinne sein in map tut ja was, denn er druckt es ja aus ....

    #include <iostream>
    #include <stdio.h>
    #include <cmath>
    #include <map>
    using namespace std;
    
    int pzz=1; //Primzahlzähler
    int vfz=1; //Vielfachenzähler
    int ruz=1; //Rundenzähler
    
    int main()
    {
        map <int,int> prufzahlen;
        map<int,int>::iterator iter;
        int x, i;
        for (x = 31; x <= 1200; x=x+30)
        {
            ruz++;
            for (i = 2; i < x; i++)
            {
                if (x%i == 0)
                    break;
                //cout<<i<<"= i \n";
            }
    
            if (i == x)
            {
                cout<<"Nr. "<<ruz<<" "<<x<<" = "<<pzz<<". Pz. \n";
                pzz++;
                 prufzahlen.insert(pair<int, int>(x, 1));
            }
            else
            {
                cout<<"Nr. "<<ruz<<" "<<x<<" = "<<vfz<<". uVf. \n";
                vfz++;
                prufzahlen.insert(pair<int, int>(x, 2));
            }
    
            for (iter = prufzahlen.begin(); iter != prufzahlen.end(); iter++)
                    {
                    cout << iter->first << " ";
                    cout << iter->second << " ";
                    cout << endl;
    
                    }
            std::cout << "Kette hat " << prufzahlen.size() << " Zahlen"<<'\n';
    
            auto first = prufzahlen.lower_bound(1);// erstes Element:
            auto last  = prufzahlen.lower_bound(20); // "eins hinter das letzte Element"
            auto is_2 = [](const map<int,int>::value_type& p){return p.second==2; };// ob es 2 sind?
    
            // das eigentliche zaehlen:
            auto n = count_if(first, last, is_2);
            cout << n << endl;
    
        }
        return 0;
    }
    


  • Sonne55 schrieb:

    Jetzt müssten wir nur noch klären, warum er nicht zählt sondern imer eine Null ausgibt.... ich will nämlich in einem weiteren Schritt first und last noch dynamisieren. Kann ich mit denen rechnen?

    Du durchsuchst nur Werte mit Key zwischen 1 und 20. Dein kleinster Key ist aber 31 also zählt er natürlich auch nichts. Mit first und last kannst du nicht rechnen. Du kannst aber mit den Zahlen rechnen die du in lower_bound einsetzt.

    Noch eine Anmerkung zum Code: Sollte deine for (x = 31; x <= 1200; x=x+30) Schleife nicht nach dem else enden? Jetzt kommt die komplette Ausgabe nach jedem Element das hinzugefügt wird.



  • sebi707 schrieb:

    Du durchsuchst nur Werte mit Key zwischen 1 und 20. Dein kleinster Key ist aber 31 also zählt er natürlich auch nichts. Mit first und last kannst du nicht rechnen. Du kannst aber mit den Zahlen rechnen die du in lower_bound einsetzt.

    aha ... ich dachte 1 und 20 sind vom 1. bis zum 20. Wertepaar. .... Kann man in Maps die Wertepaare nicht einzeln ansteuern?

    sebi707 schrieb:

    Noch eine Anmerkung zum Code: Sollte deine for (x = 31; x <= 1200; x=x+30) Schleife nicht nach dem else enden? Jetzt kommt die komplette Ausgabe nach jedem Element das hinzugefügt wird.

    Ja, das ist zur Prüfung. Wenn ich nachher richtige Zahlen einsetzte, wird das wegkommentiert.



  • Vielleicht erklärst du nochmal was du überhaupt willst. In deiner ersten Frage redest du von "Wertebereich von 10 bis 20". Darunter habe ich verstanden, dass du den Bereich der Keys einschränken willst auf den Bereich von 10 bis 20. Jetzt willst du aber das 10. bis 20. Wertepaar, egal welchen Key Bereich das abdeckt? Das ist mit einer std::map leider nicht wirklich effizient zu machen. Warum hast du dich überhaupt für eine map entschieden? Im bisher gezeigten Code hätte auch ein vector gereicht.



  • Wat ik will is...

    Er soll jetzt von der ersten Häfte der Zahlenkette mir die Abzagl der PZ ausgeben und von der zweiten Hälfte die Anzahl der Vielfachen.

    Er soll also von 1 - X/2 die Einsen Zählen und von X/2 bis X+1 die Zweien.

    Leider macht er das nicht, weil man den count if Befehl wohl nicht zwei mal hintereinander anwenden kann...

    #include <iostream>
    #include <stdio.h>
    #include <cmath>
    #include <map>
    using namespace std;
    
    int pzz=1; //Primzahlzähler
    int vfz=1; //Vielfachenzähler
    int ruz=1; //Rundenzähler
    
    int main()
    {
        map <int,int> prufzahlen;
        map<int,int>::iterator iter;
        int x, i;
        for (x = 31; x <= 1200; x=x+30)
        {
            ruz++;
            for (i = 2; i < x; i++)
            {
                if (x%i == 0)
                    break;
                //cout<<i<<"= i \n";
            }
    
            if (i == x)
            {
                cout<<"Nr. "<<ruz<<" "<<x<<" = "<<pzz<<". Pz. \n";
                pzz++;
                 prufzahlen.insert(pair<int, int>(x, 1));
            }
            else
            {
                cout<<"Nr. "<<ruz<<" "<<x<<" = "<<vfz<<". uVf. \n";
                vfz++;
                prufzahlen.insert(pair<int, int>(x, 2));
            }
    
            for (iter = prufzahlen.begin(); iter != prufzahlen.end(); iter++)
                    {
                    cout << iter->first << " ";
                    cout << iter->second << " ";
                    cout << endl;
    
                    }
            std::cout << "Kette hat " << prufzahlen.size()+1 << " Glieder"<<'\n';
    
            auto first = prufzahlen.lower_bound(1);// erstes Element:
            auto last  = prufzahlen.lower_bound((x/2)+1); // "eins hinter das letzte Element"
            auto is_1 = [](const map<int,int>::value_type& p){return p.first==1; };// ob es 1 sind?
            // das eigentliche zaehlen:
            auto n = count_if(first, last, is_1);
            cout<<"davon unten "<< n <<" PZ"<< endl;
    
            auto first = prufzahlen.lower_bound(x/2);
            auto last  = prufzahlen.lower_bound(x+1);
            auto is_2 = [](const map<int,int>::value_type& p){return p.second==2; };
            auto nx = count_if(first, last, is_2);
            cout<<"davon "<< nx <<" Vf"<< endl;
    
        }
        return 0;
    }
    

    Er sagt immer Redefinition of last and first, naja mussick ja, wenn ich was andret will, dat er zehlen soll...

    Also bei map kann man 2 Zahlen miteinander verkoppeln. Gibt es auch einen Contener, wo man 3 Zahlen miteinander verkoppeln kann?



  • Sonne55 schrieb:

    Leider macht er das nicht, weil man den count if Befehl wohl nicht zwei mal hintereinander anwenden kann...

    Wie kommst du auf solche Schlussfolgerungen? Eine Funktion die man nur einmal aufrufen kann ist reichlich sinnlos. Les doch lieber mal die Fehlermeldungen und versuche diese zu verstehen! Die Fehlermeldung wegen Redefinition von first und last liegt daran, dass du beide Variablen zweimal definierst. Nach der ersten Definition darfst du diese nicht erneut definieren. Du kannst aber den bereits vorhandenen Variablen einfach einen neuen Wert zuweisen:

    first = prufzahlen.lower_bound(x/2);
    last  = prufzahlen.lower_bound(x+1);
    

    Das geht natürlich nur wenn die Typen übereinstimmen aber hier speichern wir ja in beiden Fällen Iteratoren in eine std::map<int, int> also passt das.

    Sonne55 schrieb:

    Also bei map kann man 2 Zahlen miteinander verkoppeln. Gibt es auch einen Contener, wo man 3 Zahlen miteinander verkoppeln kann?

    Wie verstehst du verkoppeln? Verkoppeln heißt hier, dass es einen Schlüssel/Key und Werte gibt und man eine feste Zuordnung von einem Key zu einem Wert hat. In deinem Code nutzt du aber das bisher noch nicht. Wenn du einfach nur zwei oder mehr Werte speichern willst geht das auch in einem vector :

    std::vector<std::pair<int, int>> x; // vector von int Paaren
    std::vector<std::tuple<int, int, float>> y; // vector von 2 ints und einem float
    

    Bei pair kann man immer zwei Werte kombinieren und bei tuple beliebig viele. Aber jetzt gibts natürlich keinen Zusammenhang zwischen den einzelnen Werten wie bei einer map .



  • sebi707 schrieb:

    In deinem Code nutzt du aber das bisher noch nicht.

    Doch doch, sebi707, 1 repräsentiert PZ und 2 Vf, die dürfen nicht verrücken. Das ist eine feste Zuordnung.

    Ich hätte die beiden, also PZ und VF noch gern numeriert.

    Vielen Dank für die Ausführungen ....



  • Ich habs jetzt so gemacht, einfach neuen Variablen creiert. Elegant ist das nicht, und er zählt unten auch nicht. Mir ist auch nicht deutlich, warum das nach dem Weglassen der beiden "auto" funktioniert.

    #include <iostream>
    #include <stdio.h>
    #include <cmath>
    #include <map>
    using namespace std;
    
    int pzz=1; //Primzahlzähler
    int vfz=1; //Vielfachenzähler
    int ruz=1; //Rundenzähler
    
    int main()
    {
        map <int,int> prufzahlen;
        map<int,int>::iterator iter;
        int x, i;
        for (x = 31; x <= 1200; x=x+30)
        {
            ruz++;
            for (i = 2; i < x; i++)
            {
                if (x%i == 0)
                    break;
                //cout<<i<<"= i \n";
            }
    
            if (i == x)
            {
                cout<<"Nr. "<<ruz<<" "<<x<<" = "<<pzz<<". Pz. \n";
                pzz++;
                 prufzahlen.insert(pair<int, int>(x, 1));
            }
            else
            {
                cout<<"Nr. "<<ruz<<" "<<x<<" = "<<vfz<<". uVf. \n";
                vfz++;
                prufzahlen.insert(pair<int, int>(x, 2));
            }
    
           for (iter = prufzahlen.begin(); iter != prufzahlen.end(); iter++)
                    {
               //     cout << iter->first << " ";
                 //   cout << iter->second << " ";
                   // cout << endl;
    
                    }
            std::cout << "Kettelänge= " << prufzahlen.size()+1 << " "<<'\n';
            double helfte=x/2;
            cout<<"Hälfte "<<helfte<<"\n";
            int a=1;
            int b=helfte;
            auto first = prufzahlen.lower_bound(a);// erstes Element:
            auto last  = prufzahlen.lower_bound(b); // "eins hinter das letzte Element"
            auto is_1 = [](const map<int,int>::value_type& p){return p.first==1; };
            // das eigentliche zaehlen:
            auto n = count_if(first, last, is_1);
            cout<<"davon unten "<< n <<" PZ"<< endl;
    
            a=helfte;
            b=x+1;
    
            first = prufzahlen.lower_bound(a);
            last  = prufzahlen.lower_bound(b);
            auto is_2 = [](const map<int,int>::value_type& p){return p.second==2; };
            auto nx = count_if(first, last, is_2);
            cout<<"davon oben "<< nx <<" Vf und "<<((ruz/2)- nx)<<" PZ"<< endl;      
        }
        return 0;
    }
    


  • Sonne55 schrieb:

    Mir ist auch nicht deutlich, warum das nach dem Weglassen der beiden "auto" funktioniert.

    Dort wo bei der Variablendefinition das auto steht, da steht ja normalerweise der Typ der Variable. Wenn ich das ganze mit ints schreibe wird es dir vielleicht klarer:

    int a = 1;
    int a = 2; // compiliert nicht, Neudefinition von a
    

    Wenn du schon eine int Variable mit dem Namen 'a' angelegt hast darfst du keine weitere anlegen wie dir vielleicht bekannt ist. Bei auto ist das nichts anderes außer, dass du den Typ der Variable nicht selbst hinschreibst.

    Sonne55 schrieb:

    Doch doch, sebi707, 1 repräsentiert PZ und 2 Vf, die dürfen nicht verrücken. Das ist eine feste Zuordnung.

    Die Paare bleiben auch beim vector zusammen. Der Vorteil bei einer map ist aber, dass man von dem Key (welcher einzigartig sein muss) schnell den dazugehörigen Wert erhalten kann. In deinem Fall könntest du also nachschauen ob eine Zahl y eine Primzahl oder ein Vielfaches ist indem du prüfst ob prufzahlen[y] gleich 1 oder 2 ist. Genau das machst du bisher aber noch nicht.



  • sebi707 schrieb:

    Wenn du schon eine int Variable mit dem Namen 'a' angelegt hast darfst du keine weitere anlegen wie dir vielleicht bekannt ist.

    Deshalb habe ich ja zuerst

    double helfte=x/2;
            cout<<"Hälfte "<<helfte<<"\n";
            int a=3;
            int b=helfte;
    

    geschrieben und dann nochmal ohne int

    a=helfte;
            b=x+1;
    

    um den Start und Stopwert zu ändern.

    Kann das sein, daß er die untere Reihe nicht zählt (es ist der erste Block), weil Helfte Double ist, map aber mit int int angelegt ist?

    Sonne55 schrieb:

    In deinem Fall könntest du also nachschauen ob eine Zahl y eine Primzahl oder ein Vielfaches ist indem du prüfst ob prufzahlen[y] gleich 1 oder 2 ist. Genau das machst du bisher aber noch nicht.

    Das kenn ich nicht, wie geht das?



  • Sorry, aber das Programm ist richtiger Schrott.

    Das ist doch alles zusammenkopiert, ohne dass Du es verstanden hast.

    Was für Lehrmaterialien hast Du?
    Wie lautet die Aufgabe?
    Und interessehalber: Durch wen wurde die Aufgabe gestellt?

    Und dann können wir Dir eventuell ein paar wertvolle Hinweise geben.



  • Furble Wurble schrieb:

    Sorry, aber das Programm ist richtiger Schrott.

    mag sein ...aber bislang macht es, was ich will...

    Furble Wurble schrieb:

    Das ist doch alles zusammenkopiert, ohne dass Du es verstanden hast.

    stimmt für die Befehle, die ich bislang nicht kenne!

    Furble Wurble schrieb:

    Was für Lehrmaterialien hast Du?

    Nur Internet und Dirk Louis (C++) - hab vor 3 Jahren gekauft das Buch. Da steht relativ wenig zu den Algorithmen, gerade daß sie erwähnt und gelistet werden. Also, wenn jemand noch was auf DLouis aufbauendes, tiefergehendes deutssprachiges speziell für Xcode und C++ weiß, soll er das mal hier empfehlen.

    Furble Wurble schrieb:

    Wie lautet die Aufgabe?

    gar nicht - bin einfacher Imker und mache Hobbymathe in der kalten Jahreszeit. Momentan interessieren mich Primzahlen, und Programmieren macht man am besten anhand konkreter Aufgaben, damit man gezwungen ist, die Befehle gleich in richtiger Umgebung einzusetzen. Wenn man einen Schritt geschafft hat, macht man den Nächsten. So wachsen die Aufgaben. Ich will jetzt keine 1 in Programmieren vom Forum erhalten. Die Programme sollen nur die Aufgabe lösen. Das tun oft auch umständliche Programme.

    Furble Wurble schrieb:

    Und interessehalber: Durch wen wurde die Aufgabe gestellt?

    Durch mich. Durch niemanden sonst. Kein Kurs, kein Lehrpensum, keine Volkshochschule, kein Lehrer, kein Bekannter, der sich für das Programmieren interessiert, nur ich, Kakautasse und Xcode. Mein Interesse gilt der Mathematik, habe aber nur 10 Klassen. Das gute ist am Computer, daß man sich mathematische Fragen stellen kann, und diese am Computer objektiv numerisch Lösen kann. z. B. wie lautet die 333333. Primzahl? Mag zwar für andere lächerlich sein, macht aber ungemein Spaß, sowas selbst zu fragen und zu lösen.... (mithilfe der Programmierung)

    Furble Wurble schrieb:

    Und dann können wir Dir eventuell ein paar wertvolle Hinweise geben.

    so ich hoffe, was ich Dir hier bekannt habe, ist alles legal und erlaubt und auch Ok.. man weiß ja nie, was alles so verboten ist und wwer wo was dagegen hat....



  • Sonne55 schrieb:

    Furble Wurble schrieb:

    Wie lautet die Aufgabe?

    gar nicht - bin einfacher Imker und mache Hobbymathe in der kalten Jahreszeit. Momentan interessieren mich Primzahlen, und Programmieren macht man am besten anhand konkreter Aufgaben, damit man gezwungen ist, die Befehle gleich in richtiger Umgebung einzusetzen. Wenn man einen Schritt geschafft hat, macht man den Nächsten. So wachsen die Aufgaben.

    Okay. Jetzt weiß ich worum es geht, bzw. worum es nicht geht. Es geht um Spaß und Interesse. Es geht nicht um Hausaufgaben. Das eröffnet natürlich ganz neue Möglichkeiten.

    Wachsende Aufgaben verlangen umso mehr nach einer gewissen Struktur:
    Versuch mal den Primzahltest in eine Funktion auszulagern und sieh wieviel übersichtlicher das Programm wird. Z.B.

    bool ist_prim(int x);
    

    Auch das ausgeben der gesamten map prufzahlen kannst Du in eine Funktion auslagern.

    Deine magischen 1 und 2, mit der logischen Bedeutung "ist Primzahl", bzw. "ist keine Primzahl" ist mir auch ein Dorn im Auge...aber dazu vielleicht später mehr.


Anmelden zum Antworten