aus gerade zahle rausfiltern



  • Hallo Leute,

    ich muss von einer zahl gerade zahle rausfiltern und ungerade lassen
    z.b 123456 -> 135

    wo stimmt meine programmlogik nicht? in if schleife gehe ich doch nur dann wenn die zahl ungerade ist und das mache ich bis letztezahl

    #include<iostream>
    using namespace std;
    
    int main(){
    
    	int zahl, res = 1, i = 1;
    
    	cin >> zahl;
    
    	for( ; zahl ; zahl= zahl/10){
    
    		if(zahl%10/2 != 0){
    
    			res = zahl%10*i;
    
    			i *=10;
    
    		}
    
    	}
    
    	cout << res << endl;
    
    	return 0;
    
    }
    


  • Das einfachste wäre, die Zahl in einen String umzuwandeln und das Ergebnis zu filtern.
    Hier mal für positive Ganzzahlen:

    C++98/03:

    int zahl = 123456;
    
            std::stringstream stream;
            stream << zahl;
            std::string str = stream.str();
    
            std::string::iterator iter = str.begin();
            while(iter != str.end())
                    if((*iter - '0') % 2 == 0)
                            iter = str.erase(iter);
                    else 
                            ++iter;
    
            stream.str(str);
            stream >> zahl;
    
            std::cout << zahl;
    

    C++11:

    int zahl = 123456;
    
            std::string str = std::to_string(zahl);
    
            str.erase(std::remove_if(str.begin(), str.end(), [](char const c){return (c - '0') % 2 == 0;}),
                      str.end());
    
            zahl = std::stoi(str);
    
            std::cout << zahl;
    


  • ich habe keine Programmiererfahrung und wir dürfen nur mit schleifen machen und nicht mit arrays



  • Sone schrieb:

    C++11:

    str.erase(std::remove_if(str.begin(), str.end(), [](char const c){return (c - '0') % 2 == 0;}),
                      str.end());
    

    Besser:

    std::remove_copy_if(s1.begin(), s1.end(), std::back_inserter(s2),
                          [](char c){return (c-'1')%2; });
    


  • zehnelf schrieb:

    Sone schrieb:

    C++11:

    str.erase(std::remove_if(str.begin(), str.end(), [](char const c){return (c - '0') % 2 == 0;}),
                      str.end());
    

    Besser:

    std::remove_copy_if(s1.begin(), s1.end(), std::back_inserter(s2),
                          [](char c){return (c-'1')%2; });
    

    Wenn schon zwei Strings, dann gleich mit copy_if .



  • Sone schrieb:

    for(std::string::iterator iter = str.begin();iter != str.end();++iter)
                if((*iter - '0') % 2 == 0)
                    iter = str.erase(iter) - 1;
    

    Das sollte UB sein, wenn die erste Ziffer ungerade ist. Außerdem ist das O(n²). Bei sowas sollte man immer remove_if verwenden (oder der Trick mit dem swap , wenn die Reihenfolge keine Rolle spielt).



  • ipsec schrieb:

    Sone schrieb:

    for(std::string::iterator iter = str.begin();iter != str.end();++iter)
                if((*iter - '0') % 2 == 0)
                    iter = str.erase(iter) - 1;
    

    Das sollte UB sein, wenn die erste Ziffer ungerade ist. Außerdem ist das O(n²). Bei sowas sollte man immer remove_if verwenden (oder der Trick mit dem swap , wenn die Reihenfolge keine Rolle spielt).

    Verdammt! Du hast Recht, der Trick mit dem -1 war nicht gut durchdacht...

    Ich wollte halt versuchen, das ohne eine zusätzliche Funktion zu implementieren...



  • Hab es jetzt mit 'ner while-Schleife gelöst:

    std::string::iterator iter = str.begin();
            while(iter != str.end())
                    if((*iter - '0') % 2 == 0)
                            iter = str.erase(iter);
                    else 
                            ++iter;
    


  • Sone schrieb:

    Hab es jetzt mit 'ner while-Schleife gelöst:

    Da du offensichtlich den Hinweis auf O(n²) nicht verstehst: Meine Variante mit std::copy_if ist ca. 100x schneller als deine Schleifenlösung (kein Witz!!!!!!1011).



  • Und wenns inplace und eine Schleife sein soll:

    std::string::const_iterator in = s1.begin(), end=s1.end();
    std::string::iterator out = s1.begin();
    for (; in != end; ++in)
        if ((*in - '0')%2)
            *out++ = *in;
    s1.erase(out, s1.end());
    


  • khati schrieb:

    ich habe keine Programmiererfahrung und wir dürfen nur mit schleifen machen und nicht mit arrays

    #include <iostream>
    
    int main()
    { 
        int number = 1234567890;
    	int result = 0;
    	int pos = 1;
    
    	for( ; number; number /= 10 ) {
    
    		if( number % 10 % 2 == 0 ) {
    
    			result += number % 10 * pos;
    			pos *= 10;
    		}
    	}
    
    	std::cout << result << '\n';
    }
    


  • kann so mit schleifen wie ich gemacht habe nicht funktionieren?
    was ist fehler in meinem Logik?


  • Mod

    khati schrieb:

    was ist fehler in meinem Logik?

    Wenn du eine gerade Zahl durch 2 teilst, kommt nicht 0 heraus.

    Probier's mal aus 😉


Anmelden zum Antworten