C :: Aufgabe #2

2 Lösungen Lösungen öffentlich

Zahlenfolge berechnen und fortsetzen

Anfänger - C von pocki - 24.11.2012 um 19:50 Uhr
Es soll eine Zahlenfolge wiefolgt berechnet werden:
Die nacheinander folgenden gleichen Zahlen werden gezählt und zusammen mit der Zahl ausgegeben.
Aus der neu berechneten Zahlenfolge errechnet sich die nächste.

Beispiel:
1. Folge: 112
2. Folge: 2112 (2 Einser und 1 Zweier)
3. Folge: 122112 (1 Zweier, 2 Einser, und 1 Zweier)
usw.

Es soll nun mit dieser ersten Folge startend die 15. Folge berechnet und ausgegeben werden.
Wenn mehrstellige Zahlen vorkommen sind diese gleich auszugeben. Bsp: 12 Einser = 121

Lösungen:

vote_ok
von devnull (8870 Punkte) - 02.07.2013 um 15:16 Uhr
Quellcode ausblenden C-Code
/****************************************
 * folge.c    Folge erstellen
 * 
 * OS     :   GNU/Linux
 * compile:   gcc -Wall -o folge folge.c
 * usage  :   ./folge [n]  (Default n=15)
 *
 * devnull    02-07-2013                
 ****************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define MAXLOOP  15
#define MAXLEN  200


/* main */
int main( int argc, char **argv )
{
	/*
	1. Folge: 112
	2. Folge: 2112 (2 Einser und 1 Zweier)
	3. Folge: 122112 (1 Zweier, 2 Einser, und 1 Zweier)
	*/

	char s1[MAXLEN];
	char s2[MAXLEN];
	char sc[8];
	char *p1,*p2;
	int  cc,loop,maxloop; 

	maxloop=(argc>1)?atoi(argv[1]):MAXLOOP;
    strcpy(s1,"112");
    s2[0]='\0';
    
	for (loop=1;loop<=maxloop;loop++) {
		for (cc=0,p1=p2=s1;*p1;p2++) {
			if (*p1 != *p2) {
				sprintf( sc,"%d%c",cc,*p1 );
				if (strlen(s2)+strlen(sc) < MAXLEN) {
					strcat( s2,sc );
				} else {
					fprintf( stderr, "string too long, cannot continue\n" );
					return 1;  
				}
				p1=p2;
				cc=0;
			}
			cc++;
		}
		printf( "%3d : %s\n", loop,s2 );
		strcpy( s1,s2 );
		s2[0]='\0';
	}

	return 0;
}
1x
vote_ok
von mraimbot (590 Punkte) - 07.01.2019 um 00:38 Uhr
Quellcode ausblenden C-Code
///////////////////////////////////////////////////////////
//! @file Aufgabe-0002.c
//! @date 06.01.2019
//! @author Sebastian Schröder
//! @details
//! Compiler    : gcc 5.1.0
//! C-FLAGS     : -pipe -std=c99 -Wall -Wextra -pedantic -Werror -D_DEFAULT_SOURCE -O0 -g
//! Testumgebung: Windows 10 - Windows PowerShell
//!
//! Aufgabe: Zahlenfolge berechnen und fortsetzen
//! Es soll eine Zahlenfolge wiefolgt berechnet werden:
//! Die nacheinander folgenden gleichen Zahlen werden gezählt und zusammen mit der Zahl ausgegeben.
//! Aus der neu berechneten Zahlenfolge errechnet sich die nächste.
//!
//! Beispiel:
//! 1. Folge: 112
//! 2. Folge: 2112 (2 Einser und 1 Zweier)
//! 3. Folge: 122112 (1 Zweier, 2 Einser, und 1 Zweier)
//! usw.
//!
//! Es soll nun mit dieser ersten Folge startend die 15. Folge berechnet und ausgegeben werden.
//! Wenn mehrstellige Zahlen vorkommen sind diese gleich auszugeben. Bsp: 12 Einser = 121
///////////////////////////////////////////////////////////


#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>


int getNumber();
char *getStartSequence();
char *getNextSequence(char *sequence, bool toFree);
bool checkSequence(const char *sequence);
char *strdup(const char *source);


int main(int argc, char **argv) {
	int check = 0;
	int times = 0;
	char *sequence = NULL;

	if (2 <= argc) {
		check = sscanf(argv[1], "%i", ×);
		
		if (0 == check) {
			printf("Argument 1 (%s) fuer die Laenge der Folge ist ungueltig. Die Laenge muss eine Ganzzahl sein.\n", argv[1]);
		}

		if (3 <= argc) {
			sequence = (char*) strdup(argv[2]);

			if (NULL == sequence) {
				perror("Fehler bei strdup");
				return EXIT_FAILURE;
			}

			if (false == checkSequence(sequence)) {
				printf("Argument 2 (%s) fuer die Startfolge ist ungueltig. Die Startfolge darf nur Ziffern enthalten.\n", argv[2]);
				sequence = NULL;
			}
		}
	}

	if (0 == times) {
		times = getNumber();
	}

	if (NULL == sequence) {
		sequence = getStartSequence();
	}

	printf("--- START ---\n");
	printf("%4i: %s\n", 0, sequence);

	for (int i = 1; i < times; ++i) {
		sequence = getNextSequence(sequence, true);

		if (NULL == sequence) {
			perror("Fehler bei getNextSequence");
			exit (EXIT_FAILURE);
		}

		printf("%4i: %s\n", i, sequence);
	}

	free(sequence);

	return EXIT_SUCCESS;
}


int getNumber() {
	int times = 0;
	int check = 0;
	char ch;

	do {
		printf("Wie oft soll der Algorithmus auf die Folge angewendet werden?: ");
		check = scanf("%i", ×);

		while ((ch = getchar()) != '\n' && ch != EOF);

		if (1 != check) {
			printf("Eingabe ungueltig. Eingabe muss eine Ganzzahl sein.\n");
		}

		if (0 > times) {
			printf("Eingabe ungueltig. Eingabe muss positiv sein.\n");
			check = 0;
		}
	} while (check != 1);
	
	return times;
}


char *getStartSequence() {
	bool check = false;
	char sequence[256];

	do {
		printf("Startfolge eingeben: ");
		scanf("%255s", sequence);

		check = checkSequence(sequence);

		if (false == check) {
			printf("Eingabe ungueltig. Eingabe darf nur Ziffern enthalten.\n");
		}
	} while (false == check);	

	return (char*) strdup(sequence);
}


char *getNextSequence(char *sequence, bool toFree) {
	int strLength = 0;
	int tmpLength = 0;
	int counter = 0;
	char ch[2];
	char strCounter[9] = { 0 };
	char *newSequence = NULL;

	if (NULL == sequence) {
		return NULL;
	}

	strLength = strlen(sequence);
	tmpLength = strLength * 2 + 1;
	counter = 1;
	ch[0] = sequence[0];
	ch[1] = '\0';
	strCounter[0] = '\0';
	newSequence = (char*) calloc(tmpLength, sizeof(*newSequence));

	if (NULL == newSequence) {
		perror ("Fehler bei calloc");
		exit (EXIT_FAILURE);
	}
	
	for (int i = 1; i < strLength + 1; ++i) {
		if (i < strLength && sequence[i] == ch[0]) {
			counter++;
			continue;
		}

		sprintf(strCounter, "%i", counter);
		strcat(newSequence, strCounter);
		strcat(newSequence, ch);

		counter = 1;
		ch[0] = sequence[i];
	}

	newSequence = realloc(newSequence, strlen(newSequence) + 1);

	if (true == toFree) {
		free(sequence);
	}

	return newSequence;
}


bool checkSequence(const char *sequence) {
	int strLength = 0;

	if (NULL == sequence) {
		return false;
	}

	strLength = strlen(sequence);

	for (int i = 0; i < strLength; ++i) {
		if (sequence[i] < 48 || sequence[i] > 57) {
			return false;
		}
	}

	return true;
}


char *strdup(const char *source) {
	char *destination;
	
	destination = malloc(strlen(source) + 1);

	if (NULL == destination) {
		perror("malloc failed");
	}

	strcpy(destination, source);

	return destination;
}