La espada se refiere a la pregunta 17 de la oferta: el poder entero del valor

Poder entero

Tema: Ingrese el número n e imprima el número decimal desde 1 hasta el dígito n más grande en orden. Por ejemplo, si ingresa 3, entonces 1, 2, 3 se imprimirá hasta el número más grande de 3 dígitos 999.

1. Escollos
a primera vista, parece muy simple, se puede hacer en un ciclo

void PrintToMaxOfNDigits_1(int n)
{
    
    
	int number=1;
	int i=0;
	while(i++<n)
		number*=10;
	
	for(i=1;i<number;++i)
		print("%d\t",i);
}

Pero si lo piensa más detenidamente, porque no hay un rango dado de n, si n es un número grande, entonces no importa si es un entero (int) o un entero largo (long long), se desbordará.

¡Así que en realidad este es un gran problema numérico!
¿Cuál es el problema de los grandes números?
¡Por supuesto que es una cuerda!

2. Simular la suma digital en una cadena.
Debido a que el número más grande tiene n dígitos, necesitamos una cadena con una longitud de n + 1 (el dígito más popular de la cadena es \ 0). Cuando el número real no es suficiente n Último , agregue 0 a la primera mitad de la cadena.
Primero, inicialice cada dígito de la cadena en '0'. Luego, agregue 1 al número representado por la cadena cada vez y luego imprímalo. Por lo tanto, solo necesitamos hacer dos cosas: una es agregar analógico al número expresado por la cadena; la otra es imprimir el número expresado por la cadena.
Según la idea anterior, existen los siguientes códigos:

void PrintToMaxOfNDigits(int n)
{
    
    
	if(n<=0)
		return;
	char* number=new char[n+1];
	memset(number,'0',n);
	number[n]='\0';
	
	while(!Increment(number))
	{
    
    
		PrintNumber(number);
	}
	delete []number;
}

Entre ellos, la función Incremento representa el número de cadena del número aumentado en 1, y la función PrintNumber es imprimir el número

Ahora la clave es la escritura de dos funciones.

a.
¿Cómo sabe la función Incremento cuándo dejar de aumentar el número en 1, es decir, cuando se alcanzan los n dígitos máximos "9999 ... 999", lo más simple es llamar a la función strcmp después de cada aumento para comparar la cadena? número con el mayor "9999 ... 999", aunque llamar a strcmp es simple, la respuesta es que para una cadena de longitud n, la complejidad es O (n).
¿Existe una forma mejor? Por supuesto, puede ver que solo cuando se agrega 1 a "999 ... 999", se generará un acarreo sobre la base del primer carácter (el subíndice es 0). En este momento, es el número más grande de n dígitos. En este momento, Increment devuelve verdadero y el bucle se detiene.
el código se muestra a continuación:

bool Increment(char* number)
{
    
    
	bool isOverflow=false;
	int nTakeOver=0;
	int nLength=strlen(number);
	for(int i=nLength-1;i>=0;i--)
	{
    
    
		int nSum=number[i]-'0'+nTakeOver;
		if(i==nLength-1)
			nSum++;
		if(nSum>=10)
		{
    
    
			if(i==0)
				isOverflow=true;
			else
			{
    
    
				nSum-=10;
				nTakeOver=1;
				number[i]='0'+nSum;
			}
		}
		else
		{
    
    
			number[i]='0'+nSum;
			break;
		}
	}
	return isOverflow;
}

a.Función PrintNumber
Cuando el número de dígitos no sea suficiente, agregue 0 delante del número, pero no debe imprimirse al imprimir, por lo que debe imprimirse cuando el primer número no sea cero

void PrintNumber(char* number)
{
    
    
	bool isBeginning=true;
	int nLength=strlen(number);
	for(int i=0;i<nLength;++i)
	{
    
    
		if(isBeginning && number[i]!='0')
			isBeginning=false;
		
		if(!isBeginning)
		{
    
    
			printf("%c",number[i]);
		}
	}
	printf("\t");
}

3. La recursividad hace que el código sea más conciso
Si agregamos 0 al principio del número, encontraremos que todos los números decimales con n dígitos están realmente ordenados en su totalidad de 0 a 9 en el tiempo. En otras palabras, ordenamos cada dígito del número del 0 al 9 y obtenemos todos los números decimales. Es solo que cuando se imprime, el primer 0 no se imprime. La
disposición completa es fácil de expresar. Cada dígito del número puede ser un número del 0 al 9, y luego establecer el siguiente dígito. Cuando la condición final recursiva es Tenemos establezca el último dígito del número.

void PrintToMaxOfNDigits(int n)
{
    
    
	if(n<=0)
		return;
	char* number=new char[n+1];
	number[n]='\0';
	
	for(int i=0;i<10;++i)
	{
    
    
		number[0]=i+'0';
		PrintToMaxOfNDigitdRecursively(number,n,0);
	}
	delete[] number;
}

void PrintToMaxOfNDigitdRecursively(char* number,int length,int index)
{
    
    
	if(index==length-1)
	{
    
    
		PrintNumber(number);
		return;	
	}
	for(int i=0;i<10;++i)
	{
    
    
		number[index+1]=i+'0';
		PrintToMaxOfNDigitdRecursively(number,length,index+1);
	}
}

Libro de referencia: "Oferta de dedo espada"

Supongo que te gusta

Origin blog.csdn.net/rjszz1314/article/details/104175150
Recomendado
Clasificación