int als ziffern in einen array packen



  • ja weiss nicht genau wie ich es machen soll... 😕

    #include <iostream>
    using namespace std;
    
    int main()
    
    {
        int zahl, ziffern[5];
    
        zahl=12345;
        //...nun hätte ich es gern, das halt die ziffern der zahl 
        //...in den feldern des array gespeichert werden...
    }
    

    hat da jemand einen tipp für mich? 🤡



  • ich weiß nicht, aber ich glaube es geht ansich gar nicht, also mit einer standardfunktion...
    allerdings könntest du dir eine funktion bauen, die sowas macht. dafür müsstest du jede menge if-konstruktionen reinbauen...zum Beispiel:

    void explode (int iNumber, int iArray[5])
    {
        if (iNumber >= 10000 && < 20000)
        {
            iArray[0] = 1;
            iNumber -= 10000;
        }
        else if (iNumber >= 20000 && < 30000)
        {
            iArray[0] = 2;
            iNumber -= 20000;
        }
        else if (iNumber >= 30000 && < 40000)
        {
            iArray[0] = 3;
            iNumber -= 3000;
        }
        else if (iNumber >= 40000 && < 50000)
        {
            iArray[0] = 4;
            iNumber -= 40000;
        }
        else if (iNumber >= 50000 && < 60000)
        {
            iArray[0] = 5;
            iNumber -= 50000;
        }
        else if (iNumber >= 60000 && < 70000)
        {
            iArray[0] = 6;
            iNumber -= 60000;
        }
        else if (iNumber >= 70000 && < 80000)
        {
            iArray[0] = 7;
            iNumber -= 70000;
        }
        else if (iNumber >= 80000 && < 90000)
        {
            iArray[0] = 8;
            iNumber -= 80000;
        }
        else if (iNumber >= 90000 && < 100000)
        {
            iArray[0] = 9;
            iNumber -= 90000;
        }
    
        ...
    }
    

    geht 100%-ig schneller aber nur mal so als idee 😃



  • BitWax schrieb:

    ich weiß nicht, aber ich glaube es geht ansich gar nicht, also mit einer standardfunktion...
    allerdings könntest du dir eine funktion bauen, die sowas macht. dafür müsstest du jede menge if-konstruktionen reinbauen...zum Beispiel:

    void explode (int iNumber, int iArray[5])
    {
        if (iNumber >= 1000 && < 2000)
            iArray[0] = 1;
        else if (iNumber >= 2000 && < 3000)
            iArray[0] = 2;
        else if (iNumber >= 3000 && < 4000)
            iArray[0] = 3;
        else if (iNumber >= 4000 && < 5000)
            iArray[0] = 4;
        else if (iNumber >= 5000 && < 6000)
            iArray[0] = 5;
        else if (iNumber >= 6000 && < 7000)
            iArray[0] = 6;
        else if (iNumber >= 7000 && < 8000)
            iArray[0] = 7;
        else if (iNumber >= 8000 && < 9000)
            iArray[0] = 8;
        else if (iNumber >= 9000 && < 10000)
            iArray[0] = 9;
    
        ...
    }
    

    vllt. gehts auch noch schneller und besser 😃 also ist nur mal so eine idee...

    haha, also das ist ne möglichkeit...
    aber wie du schon sasgtest...
    ob das die kürzeste und elleganteste ist wage ich zu bezwifeln!
    😉



  • 123 % 10 = 3
    12 % 10 = 2
    1 % 10 = 1



  • Entenwickler schrieb:

    123 % 10 = 3
    12 % 10 = 2
    1 % 10 = 1

    naklaaaar doch!!!
    danke!
    mensch wie man manchmal den wald nicht sieht...
    😉



  • BitWax schrieb:

    ich weiß nicht, aber ich glaube es geht ansich gar nicht, also mit einer standardfunktion...

    Ähm, stringstream ?

    Deine "Idee" ist aber nicht ernstgemeint, oder doch?

    greetz, Swordfish



  • doch ist ernstgemeint, war eben das, was mir so auf die schnelle eingefallen ist, aber da kam ja schon was besseres von daher 😃



  • Hmm wenn du es aber per Module-Operator machen willst würde ich mir vorher durch lg(zahl) mal die Anzahl der Ziffern holen 😉



  • // integer to string
    std::ostringstream ss;
    ss << number;
    // temporary variables (performance)
    const std::string str_number(ss.str());
    const std::size_t size(str_number.length());
    
    // array for each item
    int* array = new int[size];
    // fill array
    for (std::size_t i(0); i < size; ++i)
        array[i] = str_number[i] - '0';
    
    // use array 
    
    // free array
    delete [] array;
    

    ... Ist eigtl. ganz einfach aber hässlich 😉

    Generell bekommst du die Ziffer an einer bestimmten Stelle in etwa so:

    #include <cmath>
    
    unsigned char get_digit(int number, unsigned int position, int log) 
    { return static_cast<unsigned char>((number / std::pow(10.0, std::floor(std::log10(number)) + 1.0 - position)) % 10); }
    

    ... Dabei wird ausgenutzt das log10(abgerundet) einer Zahl + 1 die Anzahl der Stellen einer Zahl ergibt(im Zehnersystem ...)

    (zahl / (10 ^ (Anzahl der Stellen - Position))) mod 10

    Das nimmt natürlich an, das position von Links angegeben ist. Wenn du die von Rechts angibst, kannst du dir das "Anzahl der Stellen - " sparen ...



  • Zusammengefasst die Version mit dem modulo-operator, ohne groses sstream-gefrickel 😉

    int number;
     /* ... */
    int ndigits = log10(number) + 1;
    int* digits = new int[ndigits];
    while(number) {
      digits[--ndigits] = number%10;
      number/=10;
    }
    


  • pumuckl schrieb:

    Zusammengefasst die Version mit dem modulo-operator, ohne groses sstream-gefrickel 😉

    /* ... */
    

    Zusammengefasst die Version mit dem Modulo-Operator, ohne schlimmere Fehler:

    #include <cmath>
    
    template< typename T_dest, typename T_num >
    size_t get_digits( T_dest **dest, T_num number ) {
    
    	if( !number ) {
    
    		*dest = new T_dest[ 1 ];
    		**dest = 0;
    		return 1;
    	}
    
    	size_t num_digits = log10( static_cast< float >( number ) ) + 1;
    	*dest = new T_dest[ num_digits ];
    
    	for( size_t i = num_digits; i; number /= 10, --i ) {
    
    		( *dest )[ i - 1 ] = number % 10;
    	}
    
    	return num_digits;
    }
    

    greetz, Swordfish



  • Na komm ... Referenzen sind doch noch etwas schöner ...

    #include <cmath>
    
    template< typename T_dest, typename T_num >
    size_t get_digits(T_dest*& dest, T_num number) 
    {
        if (!number ) 
        {
            dest = new T_dest[ 1 ]();
            return 1;
        }
    
        const std::size_t num_digits(std::log10(static_cast< float >( number ) ) + 1);
        dest = new T_dest[ num_digits ];
    
        for (size_t i(num_digits); i; number /= 10, --i) 
            dest[ i - 1 ] = number % 10;
    
        return num_digits;
    }
    

    😃 naja egal 😉



  • (D)Evil schrieb:

    Na komm ... Referenzen sind doch noch etwas schöner ...

    Dir werd' ich's wohl nie Recht machen können... 🙄 😉

    greetz, Swordfish

    PS: std::size_t ... ist size_t nicht irgendwann als Keyword in den Sprachstandard eingegangen, oder ist das eine Compilererweiterung?



  • Das hatten wir doch schon, hier ist eine Funktion, die eine Zahl in ihre Dezimalziffern zerlegt.

    Und in diesem Fall hieße es einfach:

    #include <iostream>
    
    int main()
    {
        using namespace std;
        int zahl = 1234;
        int ziffern[5];
        int* end = dezimal_ziffern( zahl, ziffern );
    
        for( int* p = ziffern; p != end; ++p )
            cout << *p << " " << endl;
        cout << endl;
        return 0;
    }
    

    .. und wenn Ihr das in ein dynamisches Array packen wollt, so gibt's doch vector (was denn sonst):

    #include <iostream>
    #include <vector>
    #include <iterator>
    
    int main()
    {
        using namespace std;
        int zahl = 1234;
        vector< int > ziffern;
        dezimal_ziffern( zahl, back_inserter( ziffern ) );
        // ... 
        return 0;
    }
    

    Gruß
    Werner



  • nice 😉

    greetz, Swordfish



  • Swordfish schrieb:

    pumuckl schrieb:

    Zusammengefasst die Version mit dem modulo-operator, ohne groses sstream-gefrickel 😉

    /* ... */
    

    Zusammengefasst die Version mit dem Modulo-Operator, ohne schlimmere Fehler:

    hups wo waren denn bei mir die schlimmeren Fehler?



  • Swordfish schrieb:

    PS: std::size_t ... ist size_t nicht irgendwann als Keyword in den Sprachstandard eingegangen, oder ist das eine Compilererweiterung?

    Laut '98er C++-Standard liegt size_t im Namensraum std und muss über den passenden Bibliotheksheader definiert werden. In einer Notiz zu 3.7.3 heisst es dort:

    However, referring to std, std::bad_alloc, and
    std::size_t is ill-formed unless the name has been declared by including the appropriate header.



  • pumuckl schrieb:

    Zusammengefasst die Version mit dem modulo-operator, ohne groses sstream-gefrickel 😉

    int number;
     /* ... */
    int ndigits = log10(number) + 1;
    int* digits = new int[ndigits];
    while(number) {
      digits[--ndigits] = number%10;
      number/=10;
    }
    

    pumuckl schrieb:

    hups wo waren denn bei mir die schlimmeren Fehler?

    zunächst übersetzt der Code nicht unbedingt, da log10(int) nicht existiert und der Compiler nicht weiß, ob er log10(float) oder log10(double) hernehmen soll (Fehlermeldung: ambiguous call to overloaded function). Und zum anderen hat der Anwender am Ende keinerlei Informationen darüber, wie viele Ziffern jetzt in digits[] stehen ... er kann faktisch gar nicht auf die Ziffern zugreifen.

    Ich stelle bei mir selber auch immer wieder fest: ein gar nicht oder nicht ausreichend getestetes Codesegment enthält fast immer Fehler.

    Gruß
    Werner



  • Ok *zerknirscht*, das mit den digits war blöd, beim testen "wusste" ich ja immer wieviele Ziffern es sein müssten. das log10(int) hat er bei mir allerdings gefressen ohne zu mosern.

    #include <cmath>
    #include <cstddef>
    
    unsigned int number;
     /* ... */
    std::size_t ndigits = (number ? std::log10(number*1.0f)+1 : 1);
    unsigned char* digits = new unsigned char[ndigits](0);
    for(std::size_t n=ndigits; number!=0; number/=10)
      digits[--n] = number%10;
    

    Sollte es beheben.



  • pumuckl schrieb:

    Sollte es beheben.

    number = 0; ?

    greetz, Swordfish



  • habs reineditiert, ebenso wie vorzeichenlose Typen um negative number zu vermeiden. Solche Dinge zu beruecksichtigen (Spezialfaelle wie numbers==0) muss ich mir noch einpruegeln, daher danke Swordfish


Anmelden zum Antworten