L'épée fait référence à la question 17-la puissance entière de la valeur

Puissance entière

Sujet: Entrez le nombre n et imprimez le nombre décimal de 1 au plus grand n chiffres dans l'ordre. Par exemple, si vous entrez 3, alors 1, 2, 3 seront imprimés jusqu'au plus grand nombre à 3 chiffres 999.

1. Pièges
à première vue, cela semble très simple, cela peut être fait en une seule boucle

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);
}

Mais si vous y réfléchissez plus attentivement, car il n'y a pas de plage donnée de n, si n est un grand nombre, peu importe si c'est un entier (int) ou un entier long (long long), il débordera.

Donc, en fait, c'est un gros problème!
Quel est le problème des grands nombres?
Bien sûr, c'est une chaîne!

2. Simulez une addition numérique sur une chaîne.
Comme le plus grand nombre est composé de n chiffres, nous avons besoin d'une chaîne d'une longueur de n + 1 (le chiffre le plus courant de la chaîne est \ 0). Lorsque le nombre réel n'est pas suffisant n Dernier , ajoutez 0 à la première moitié de la chaîne.
Tout d'abord, initialisez chaque chiffre de la chaîne à «0». Ajoutez ensuite 1 au nombre représenté par la chaîne à chaque fois, puis imprimez-le. Par conséquent, nous n'avons besoin que de deux choses: l'une consiste à ajouter analogique au nombre exprimé par la chaîne; l'autre consiste à imprimer le nombre exprimé par la chaîne.
Selon l'idée ci-dessus, il existe les codes suivants:

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;
}

Parmi eux, la fonction Incrément représente le numéro de chaîne numérique augmenté de 1, et la fonction PrintNumber consiste à imprimer le nombre

Maintenant, la clé est l'écriture de deux fonctions

a.
Comment la fonction Incrément sait-elle quand arrêter d'augmenter le nombre de 1, c'est-à-dire que lorsque le maximum de n chiffres "9999 ... 999" est atteint, le plus simple est d'appeler la fonction strcmp après chaque augmentation pour comparer la chaîne nombre avec le plus grand "9999 ... 999", bien que l'appel de strcmp soit simple, la réponse est que pour une chaîne de longueur n, la complexité est O (n).
Y a-t-il un meilleur moyen? Bien sûr, vous pouvez voir que seulement lorsque 1 est ajouté à "999 ... 999", un report sera généré sur la base du premier caractère (l'indice est 0). À ce stade, il s'agit du plus grand nombre à n chiffres. À ce stade, Increment renvoie true et la boucle s'arrête.
code montrer comme ci-dessous:

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;
}

Fonction a.PrintNumber
Lorsque le nombre de chiffres n'est pas suffisant, ajoutez 0 devant le nombre, mais il ne doit pas être imprimé lors de l'impression, il doit donc être imprimé lorsque le premier n'est pas nul.

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 récursion rend le code plus concis
Si nous ajoutons 0 au début du nombre, nous constaterons que tous les nombres décimaux à n chiffres sont en fait disposés en entier de 0 à 9 dans le temps. En d'autres termes, nous organisons chaque chiffre du nombre de 0 à 9, et nous obtenons tous les nombres décimaux. C’est juste que lors de l’impression, le premier 0 n’est pas imprimé. La
disposition complète est facile à exprimer. Chaque chiffre du nombre peut être un nombre compris entre 0 et 9, puis définir le chiffre suivant. Lorsque la condition de fin récursive est Nous avons définissez le dernier chiffre du numéro.

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);
	}
}

Ouvrage de référence: "Sword Finger Offer"

Je suppose que tu aimes

Origine blog.csdn.net/rjszz1314/article/details/104175150
conseillé
Classement