bingo88
PCGH-Community-Veteran(in)
AW: [C] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...
Mit zwei Änderungen läuft es bei mir durch:
Ich habe die Stellen mit /* FIX ... */ markiert. Du hast jeweils bei einem Element zu früh angefangen (Array-Index beginnt bei 0 und nicht bei 1, d. h. du darfst nur von 0 bis len - 1 bzw. len - 1 bis 0 laufen). Dazu ist Einzelschritt-Debugging ganz hilfreich: Einfach ein paar Breakpoints an geeigneten Stellen setzen, sich durchhangeln und die Schritte mit dem kodierten String vergleichen.
Mit zwei Änderungen läuft es bei mir durch:
Code:
#include <stdio.h>
#include <math.h>
int checkLength(char *s)
{
int i = 0, j = 0, k = 0, count1 = 0, count2 = 0, length1 = 0,
length2 = 0;
while (*(s + length1) != '\0')
{
length1++;
}
/* FIX off by one */
i = length1 - 1; /* length1 = Länge des codierten Strings. */
while (i > 0)
{ /* Es muss von hinten begonnen werden, weil nur so die char Ziffern bei der int-Berechnung die richtigen Stellenwerte erhalten. */
if (*(s + i) >= 48 && *(s + i) <= 57)
{ /* Zahl gefunden. */
k++;
count1 = (*(s + i) - 48);
count2 += (count1 * (int) pow(10., k - 1)); /* Berechne Gesamtzahl als integer. */
if (*(s + i - 1) >= 65 && *(s + i - 1) <= 90)
{
length2 += count2;
length2--; /* Zahlen geben bereits Vorkommen des jeweiligen Buchstabens an. Dieser darf nicht auch noch dazugezählt werden. */
}
}
else if (*(s + i) >= 65 && *(s + i) <= 90)
{ /* Buchstabe gefunden. */
length2++;
count2 = 0;
k = 0;
}
i--;
}
return (length2 + 1);
}
/*
Funktion calc nötig, um Zahlenstellen in der richtigen Reihenfolge ausgeben lassen zu können
durch verkleinern der entsprechenden Indexe von *s anhand des Rückgabewertes.
*/
int calcSteps(int num)
{
int temp1 = num, temp2 = 0, count = 0;
while (temp1 > 0)
{
temp2 = temp1 % 10;
temp1 /= 10;
count++; /* Ermittle Anzahl der nötigen Rechenschritte und somit auch die Anzahl der Stellen der Zahl bzw. nötigen Indexe im Feld. */
}
return count;
}
double encode_runlength(char *s)
{
int i = 0, j = 1, k = 0, temp1 = 0, temp2 = 0, count1 = 0, count2 = 1,
length = 0;
double ratio = 0.0;
while (*(s + length) != '\0')
{
length++;
}
/* Codieren des Original-Strings: */
while (*(s + i) != '\0')
{
if (*(s + i) != *(s + j))
{ /* Sobald Buchstabe nicht mehr gleich seinem Nachfolger ist, prüfe: */
if ((j - count1) == 1)
{ /* Einmaliges Vorkommen? */
*(s + k) = *(s + i); /* Überschreibe Feld von vorne beginnend mit Buchstaben ... */
k++; /* ... und springe im Index um 1 weiter. */
count1 = j;
}
else
{ /* Mehrmaliges Vorkommen? */
*(s + k) = *(s + i); /* Überschreibe Feld von vorne beginnend mit Buchstaben. */
if ((j - count1) > 9)
{ /* Vorkommen größer als 9: */
temp1 = (j - count1);
while (temp1 > 0)
{ /* Zerlege (An)Zahl in ihre einzelnen Stellen. */
temp2 = temp1 % 10;
temp1 /= 10;
count2++; /* Zähle Rechenschritte mit um Anzahl der nötigen Stellen und somit Indexe zu ermitteln. */
*(s + k + (calcSteps(temp1) + 1)) = (char) (temp2 + 48); /* Überschreibe entsprechend viele Feldelemente mit den Stellen der Vorkommenszahl. */
}
k += count2; /* Dann springe entsprechend viele Indexe weiter, um an die nächste zu überschreibende Stelle zu gelangen. */
count1 = j;
count2 = 1;
}
else
{ /* Vorkommen bis 9: */
*(s + k + 1) = (char) ((j - count1) + 48);
k += 2; /* Ein Buchstabe und seine Zahl wurden geschrieben. Springe daher 2 Indexe weiter. */
count1 = j;
}
}
}
i++;
j++;
}
ratio = (double) k; /* ratio enthält am Ende der Schleife die Länge der Codierung. */
*(s + (int) ratio) = '\0'; /* Hänge an die Codierung noch eine Nullterminierung an. */
printf("%s", s); /* Ausgabe: Codierter String */
return ((ratio * 100) / (double) length);
}
int decode_runlength(char *s)
{
int i = 0, j = 0, k = 0, temp1 = 0, temp2 = 0, count1 = 0, count2 = 0,
length1 = 0, length2 = 0;
while (*(s + length2) != '\0')
{
length2++;
}
/* Decodiere String: */
length1 = checkLength(s);
i = length1 - 1; /* length1 = Originallänge des Strings. */
/* FIX off by one */
j = length2 - 1; /* length2+1 = Länge des codierten Strings. */
while (i > 0)
{
if (*(s + j) >= 48 && *(s + j) <= 57)
{ /* Zahl gefunden. */
k++;
count1 = (*(s + j) - 48);
count2 += (count1 * (int) pow(10., k - 1)); /* Berechne Gesamtzahl als integer und ... */
if (*(s + j - 1) >= 65 && *(s + j - 1) <= 90)
{
temp1 = (count2 - 1);
temp2 = count2;
}
while (temp1 > 0)
{ /* ... überschreibe Feld von hinten beginnend gemäß dieser Anzahl mit dem zugehörigen Buchstaben. */
*(s + i) = *(s + j - calcSteps(temp2) + (k - 1));
temp1--;
i--;
}
}
else if (*(s + j) >= 65 && *(s + j) <= 90)
{ /* Buchstabe gefunden. */
*(s + i) = *(s + j);
i--;
count2 = 0;
k = 0;
}
j--;
}
*(s + length1) = '\0'; /* Hänge an die Decodierung noch eine Nullterminierung an. */
printf("%s", s); /* Ausgabe: Decodierter String */
return 0;
}
int main(void)
{
//int main(int argc, char *argv[]) {
//char *s = argv[1];
char s[] = "ABBBBBBBBAAAAAAAAACCCCCCCCCCCCCCCCCCD";
//char s[] = "ABB";
int i = 0;
/* Kleinbuchstaben in Großbuchstaben umwandeln */
while (*(s + i) != '\0')
{
if (*(s + i) >= 97 && *(s + i) <= 122)
{
*(s + i) -= 32;
}
i++;
}
printf("Original: %s", s);
printf("\nCodiert: ");
printf("\nVerk%crzung: %.0lf %%\n", 129, (100 - encode_runlength(s)));
printf("Decodiert: ");
decode_runlength(s);
printf("\n\n");
return 0;
}
Zuletzt bearbeitet: