Hilfe zu einem Algorithmus - String aus einem char array in eine 2D-Matrix übertragen



  • Werte Forummitglieder,

    zum besseren Verständnis von Zeichenketten und Algorithmen habe ich mir selbst folgende Aufgabe gestellt:

    Übertrage einen String (in meinem Fall AMPELMAENNCHENFARBEN) fester Größe (in meinem Fall ein char array mit 20 Zeichen) so in eine Matrix, dass Folgendes ausgegeben wird:

    AMPEL quasi in Form eines Wirbels
    NFARM
    ENEBA
    HCNNE

    Mein Code:

    #include <stdio.h>
    
    void StringMatrix(char* str)
    {
        char strMatrix[4][3];
        int iMin = 0, iMax = 4, jMin = 0, jMax = 3, index = 0;
    
        for(int i = 0; i <= 4; i++)
        {
            for(int j = 0; j <= 3; j++)
            {
                strMatrix[i][j] = ' ';
            }
        }
    
        while(str[index] != '\0')
        {
            for(iMin; iMin <= iMax; iMin++)
            {           
                if(index == 20){ break; }else{ index++; }
                strMatrix[iMin][jMin] = str[index - 1];            
            }
    
            jMin++; iMin--;
    
            for(jMin; jMin <= jMax; jMin++)
            {
                if(index == 20){ break; }else{ index++; }
                strMatrix[iMin][jMin] = str[index - 1];           
            }
    
            if(index == 18){ iMin = 1;}else{ iMin = 0;}
            iMax--;       
    
            for(iMax; iMax >= iMin; iMax--)
            {
                if(index == 20){ break; }else{ index++; }
                strMatrix[iMax][jMax] = str[index - 1];  
            }
    
            jMax--; jMin = 1;
    
            for(jMax; jMax >= jMin; jMax--)
            {
                if(index == 20){ break; }else{ index++; }
                strMatrix[iMin][jMax] = str[index - 1]; 
            }
    
            iMin++; iMax = 3; jMax = 2;     
    
        }
    
        for(int j = 0; j <= 3; j++)
        {
            for(int i = 0; i <= 4; i++)
            {
                putchar(strMatrix[i][j]);
            }
                printf("\n");
        } 
    
    }
    
    int main(int argc, char** argv) {
    
        char str[20] = "AMPELMAENNCHENFARBEN";
    
        StringMatrix(str);
    
        getchar();
        return 0;
    }
    

    Folgendes Problem tritt auf:

    -> Die Matrix wird nicht korrekt ausgegeben (Ich weiß nicht woran das liegt)

    Folgende Fragen habe ich:

    1. Der Code ist nicht wirklich effizient (nur für einen String fester Größe). Gibt es einen Algorithmus, mit dem man das Ganze vollkommen dynamisch (String mit dynamischer Größe, Matrix wächst dynamisch mit) lösen könnte?

    2. Wie könnte ich die if-Bedingungen in den for-Schleifen vereinfachen?

    Ich danke euch für eure Hilfe.

    Grüße
    Eric



  • Hallo,

    deine Matrix ist falsch dimensioniert:

    char strMatrix[5][4];
    

    Angegeben wird die Anzahl - nicht der höchste Index!

    Und üblich ist es daher auch diese Werte per 'kleiner' in den Schleifen zu vergleichen:

    for(int i = 0; i < 5; i++)
    {
       for(int j = 0; j < 4; j++)
       {
          strMatrix[i][j] = ' ';
       }
    }
    

    Und noch besser ist es, diese Werte als Konstanten zu hinterlegen:

    #define MaxX 5
    #define MaxY 4
    
    char strMatrix[MaxX][MaxY];
    

    Für zur Laufzeit dynamische Arrays müßtest du per malloc() Speicher allokieren!



  • Dein String ist auch zu klein. 20 Zeichen plus Endekennung '\0' ergibt 21 ZEichen.

    Darum überlässt man den Compiler das dimensionieren:

    char str[] = "AMPELMAENNCHENFARBEN";
    


  • kakashi83 schrieb:

    Werte Forummitglieder,

    zum besseren Verständnis von Zeichenketten und Algorithmen habe ich mir selbst folgende Aufgabe gestellt:

    Übertrage einen String (in meinem Fall AMPELMAENNCHENFARBEN) fester Größe (in meinem Fall ein char array mit 20 Zeichen) so in eine Matrix, dass Folgendes ausgegeben wird:

    AMPEL quasi in Form eines Wirbels
    NFARM
    ENEBA
    HCNNE

    Mein Code:

    #include <stdio.h>
    
    void StringMatrix(char* str)
    {
        char strMatrix[4][3];
        int iMin = 0, iMax = 4, jMin = 0, jMax = 3, index = 0;
        
        for(int i = 0; i <= 4; i++)
        {
            for(int j = 0; j <= 3; j++)
            {
                strMatrix[i][j] = ' ';
            }
        }
        
        while(str[index] != '\0')
        {
            for(iMin; iMin <= iMax; iMin++)
            {           
                if(index == 20){ break; }else{ index++; }
                strMatrix[iMin][jMin] = str[index - 1];            
            }
             
            jMin++; iMin--;
            
            for(jMin; jMin <= jMax; jMin++)
            {
                if(index == 20){ break; }else{ index++; }
                strMatrix[iMin][jMin] = str[index - 1];           
            }
            
            if(index == 18){ iMin = 1;}else{ iMin = 0;}
            iMax--;       
    
            for(iMax; iMax >= iMin; iMax--)
            {
                if(index == 20){ break; }else{ index++; }
                strMatrix[iMax][jMax] = str[index - 1];  
            }
            
            jMax--; jMin = 1;
            
            for(jMax; jMax >= jMin; jMax--)
            {
                if(index == 20){ break; }else{ index++; }
                strMatrix[iMin][jMax] = str[index - 1]; 
            }
            
            iMin++; iMax = 3; jMax = 2;     
    
        }
        
        for(int j = 0; j <= 3; j++)
        {
            for(int i = 0; i <= 4; i++)
            {
                putchar(strMatrix[i][j]);
            }
                printf("\n");
        } 
        
    }
    
    int main(int argc, char** argv) {
    
        char str[20] = "AMPELMAENNCHENFARBEN";
        
        StringMatrix(str);
        
        getchar();
        return 0;
    }
    

    Folgendes Problem tritt auf:

    -> Die Matrix wird nicht korrekt ausgegeben (Ich weiß nicht woran das liegt)

    Folgende Fragen habe ich:

    1. Der Code ist nicht wirklich effizient (nur für einen String fester Größe). Gibt es einen Algorithmus, mit dem man das Ganze vollkommen dynamisch (String mit dynamischer Größe, Matrix wächst dynamisch mit) lösen könnte?

    2. Wie könnte ich die if-Bedingungen in den for-Schleifen vereinfachen?

    Ich danke euch für eure Hilfe.

    Grüße
    Eric

    Ich habe mal vor langer Zeit etwas ähnliches in Java gebastelt. Es erzeugt eine spiralförmige gefüllte, quadratische Matrix mit Werten die hochgezählt werden. Vielleicht kannst du das ja irgendwie verwerten.

    Die Variable "val" könnte z.B ein Index in deinen String sein.

    Btw, die Klasse "Numberfield" ist im Prinzip bloß ein 2D-Array.

    /**
         * Create a spiral matrix
         * @param xy Size of both width and height of quadratic matrix
         * @param val start value
         * @return the new matrix
         */
        public static NumberField countedSpiralRightDown (int xy, double val)
        {
            NumberField n = new NumberField (xy, xy);
    
            int min = 0;
            int max = xy;
            int loops = xy / 2;
    
            for (int r = 0; r < loops; r++)
            {
                for (int s = min; s < max; s++)
                {
                    n.values[min][s] = val++;
                }
    
                for (int s = min + 1; s < max; s++)
                {
                    n.values[s][max - 1] = val++;
                }
    
                for (int s = max - 2; s >= min; s--)
                {
                    n.values[max - 1][s] = val++;
                }
    
                for (int s = max - 2; s >= min + 1; s--)
                {
                    n.values[s][min] = val++;
                }
    
                min++;
                max--;
            }
            // Set center value when square is odd
            if ((xy & 1) == 1)
            {
                n.values[loops][loops] = val;
            }
    
            return n;
        }
    


  • kakashi83 schrieb:

    AMPELMAENNCHENFARBEN

    Meiner bescheidenen Erfahrung nach ist es hier vielleicht am schnellsten, die aufgerundete Wurzel der Länge zu ziehen für die Ausgabegröße und dann einen (evtl ein Schattenarray of bool mitgeführt (bevorzugt mit Todesrand)) An-Der-Wand-Lang-Automaten drauf anzusetzen.

    Im konkreten Fall kannste viel besser mit der Wurzel aufsetzen und es durchnudeln.
    Nudele es bitte durch. Per Schreibtischtest. Nein! Per Mensch eben. Mach es per Mensch mit verschiedenen Anzahlen und mach es so oft und so lange (zum Beispiel mit Spielkarten), bis es per Mensch *sicher* sitzt. Dann kannste den Code einklöppeln. Er wird fehlerfrei und effizient sein.



  • Ich danke allen für ihre hilfreichen Antworten. Ihr habt mir sehr geholfen.

    Beste Grüße
    Eric


Log in to reply