Quersumme einer Zahl



  • Hallo

    Ich möchte die Quersumme einer Zahl mittels Rekursion berechen.

    Ok vergesst erst mal die Rekursion.

    Wie komme ich am einfachsten auf die einzelnen Zahlen-Werte/Ziffern ?

    Also
    int x = 345 -> 3 + 4 + 5

    Grüße



  • Hallo,

    stell Dir doch zuerstmal die Frage: Wie kommst Du auf die letzte Zimmer. Hast Du da eine Idee?

    Und wenn Du das weißt, kannst Du Dich fragen: Wie machst Du aus der Zehnerstelle eine Einerstelle? Wenn Du auch das weißt, kannst Du genau so verfahren.



  • Guck dir mal den

    %
    

    operator und Integer Division an.



  • Du dividierst die Zahl durch 10 und merkst dir den rest. Dazu benötigst du den Modulo-operator.

    Gruß
    Syntax



  • Ah viel zu komplziert Gedacht 😃
    Danke für das % ... reicht schon.



  • Wenn die Zahl eh eingegeben wird, ist selbst der % noch zu kompliziert gedacht 😉



  • pumuckl schrieb:

    Wenn die Zahl eh eingegeben wird, ist selbst der % noch zu kompliziert gedacht 😉

    Wie meinst du das? Aufklärung?



  • out schrieb:

    pumuckl schrieb:

    Wenn die Zahl eh eingegeben wird, ist selbst der % noch zu kompliziert gedacht 😉

    Wie meinst du das? Aufklärung?

    ???
    Einfach String einlesen und std::accumulate mit 'nem Operator (Lambda o. Funktion) drüber laufen lassen?

    Edit: Ginge bestimmt auch ohne Operator, einfach die Anzahl Zeichen multipliziert mit '0' abziehen.

    Edit²:
    Hier zum Spaß eine Zahlbasis-unabhängige Version ohne Modulo:

    template<typename T>
    typename std::enable_if<std::is_integral<T>::value, T>::type
            digit_sum(T value, uint8_t const base = 10)
    {
            uint8_t start_exp = 0;
    
            while(std::pow(base, start_exp + 1) <= value)
                    ++start_exp;
    
            T rval = 0;
    
            for(T temp;value;--start_exp)
                    for(temp = std::pow(base, start_exp);temp <= value;++rval)
                            value -= temp;
    
            return rval;
    }
    

    🤡



  • Sone schrieb:

    ...

    Wenn pumuckl das gemeint hat, bleib ich bei dem %-Operator. Da ist wenigtens für jedermann gleich ersichtlich, was gemacht wird.



  • Sehr viel komplizierter, aber besser kann ich es noch nicht. Ist leider iterativ gelöst und ohne elegante Templates:

    int i = 345;
        stringstream ss;
        ss << i;
        string s(ss.str());
        int quersumme = 0, temp;
        for(string::const_iterator it = s.begin(); it < s.end(); ++it)
        {
            stringstream digit;
            digit << *it;
            digit >> temp;
            quersumme += temp;
        }
    
        cout << "Quersumme von " << i << " ist gleich " << quersumme << endl;
    


  • out schrieb:

    Sone schrieb:

    ...

    Wenn pumuckl das gemeint hat, bleib ich bei dem %-Operator. Da ist wenigtens für jedermann gleich ersichtlich, was gemacht wird.

    Nein, er meinte einfach die einzelnen Zeichen durchgehen und aufsummieren. Das ist tatsächlich ziemlich trivial, aber ich wollte halt keine Schleife dafür benutzen.



  • out schrieb:

    Wenn pumuckl das gemeint hat,

    Zumindest nicht den Quellcode den er da hat 😉
    Ganz simples Beispiel:

    template<class CharIter> //kann char const* oder ein istreambuf_iterator oder ähnliches sein.
    int qsum(CharIter first, CharIter last)
    {
      int q = 0;
      for(; first != last; ++first)
      {
        unsigned char n = *first - '0';
        if (n > 9) return -1; //keine Ziffer
        q += n;
      }
      return q;
    }
    
    int main()
    {
      std::string s = "128";
      std::cout << qsum(s.begin(), s.end()); //1
      s.append("r");
      std::cout << qsum(s.begin(), s.end()); //-1
    }
    

    Kann man natürlich noch mit char_traits würzen, wenn man will auch mit irgendwelchen delimitern usw, ums generischer zu machen, oder statt des negativen Rückgabewertes eine Exception werfen, aber ich denke man verstehts so am Besten...



  • [quote="Sone"][quote="out"]

    pumuckl schrieb:

    ???
    Einfach String einlesen und std::accumulate mit 'nem Operator (Lambda o. Funktion) drüber laufen lassen?

    Na das mit dem Lambda das ist mir nicht geheuer 😃
    Kannst du das mal schonend erklären ? :D.

    Vor allem wie am Anfang es geht ja um eine Lösung mittels Rekursion.

    int quer(int z)
    {
    	int temp = z/10;
    
    	if (temp == 0)
    	{
    		return z;
    	}
    	else
    	{
    		return z % 10 + quer(temp);
    	}
    }
    

    Deswegen hab ich mir das so gedacht ... kann man vielleicht noch etwas optimieren ...

    PS:
    http://msdn.microsoft.com/de-de/library/vstudio/dd293608.aspx

    Oh oh oh gibts das wo leichter erklährt ? 🤡 ...
    Wo ist da denn ein Lambda ? ... Das kann ja keiner mehr lesen .. 😮



  • Mit accumulate sähe das so aus:

    std::string zahl="12345";
    std::cout<<std::accumulate( zahl.begin(), zahl.end(), 0, [](int x,char y){return x+y-'0';});
    

    Eine Lambda Funktion ist einfach eine anonyme Funktion, die keinen Namen hat und die ich an Ort und Stelle definieren kann.
    Man könnte auch einen Funktor oder eine normale Funktion nehmen.

    std::accumulate geht einfach mit einem Starwert und einer Funktion einen Bereich durch und wendet die Funktion auf jeden Wert des Bereichs an.
    Kennt an vielleicht aus funktionalen Sprachen als fold(r/l).

    Bei diesem Beispiel:

    (((((0+1)+2)+3)+4)+5)
    

    Btw das kürzeste einfache wäre wahrscheinlich dies:

    int quer(int z)
    {
        return (z?z%10+quer(z/10):0);
    }
    


  • return (z?z%10+quer(z/10):0);
    

    Du bist ein Drei-Sterne Programmierer.

    if(z)
        return z % 10 + quer( z / 10 );
    
    return 0;
    


  • Sone schrieb:

    Btw, du bist ein Drei-Sterne Programmierer.

    An was machst du das aus? 😕


  • Mod

    out schrieb:

    Sone schrieb:

    Btw, du bist ein Drei-Sterne Programmierer.

    An was machst du das aus? 😕

    Sone hat sich heute noch nicht genug profiliert, daher muss er sinnlos rummotzen mit Worten, die er nicht richtig versteht. Das ist Grund genug.



  • out schrieb:

    Sone schrieb:

    Btw, du bist ein Drei-Sterne Programmierer.

    An was machst du das aus? 😕

    Ich hab mich vertan. Er meine die kürzeste Schreibweise, da ist natürlich der ternäre Operator besser.

    Er benutzt statt einer if() -Anweisung den operator?: , obwohl hier eine if -Anweisung schöner wäre; das war mein ursprünglicher Gedanke.



  • Butterbrot schrieb:

    Sehr viel komplizierter, aber besser kann ich es noch nicht. Ist leider iterativ gelöst und ohne elegante Templates:

    Im Allgemeinen wird wohl immer der %-Operator benutzt. Dass du darauf nicht kommst, liegt vielleicht daran, dass du in eine falsche Richtung denkst. Hast du schonmal eine Dezimalzahl in eine Hexzahl oder in eine Binärzahl umgerechnet? Die Berechnung einer Quersumme ist nichts anderes, außer dass du vom Dezimalsystem ins Dezimalsystem umrechnest. Am Schluss hängst du nur nicht alle Ziffern aneinander, sondern addierst sie auf.



  • Ich finde ?: schoener, schon alleine der Symmetrie wegen.


Anmelden zum Antworten