Sword refers to offer question 17-the integer power of the value

Integer power

Topic: Enter the number n, and print out the decimal number from 1 to the largest n-digit in order. For example, if you enter 3, then 1, 2, 3 will be printed up to the largest 3-digit number 999.

1. Pitfalls
at first glance, it seems very simple, it can be done in one loop

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

But if you think about it more carefully, because there is no given range of n, if n is a large number, then no matter if it is an integer (int) or a long integer (long long), it will overflow.

So actually this is a big number problem!
What is the problem of large numbers?
Of course it is-a string!

2. Simulate digital addition on a string.
Because the largest number is n digits, we need a string with a length of n+1 (the most popular digit of the string is \0). When the actual number is not enough n Last, add 0 to the first half of the string.
First, initialize each digit of the string to '0'. Then add 1 to the number represented by the string each time, and then print it out. Therefore, we only need to do two things: one is to add analog to the number expressed by the string; the other is to print the number expressed by the string.
According to the above idea, there are the following codes:

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

Among them, the function Increment represents the number string number increased by 1, and the function PrintNumber is to print the number

Now the key is the writing of two functions

a.
How does the Increment function know when to stop increasing the number by 1, that is, when the maximum n digits "9999...999" are reached, the simplest is to call the strcmp function after each increase to compare the string number with the largest "9999...999", although calling strcmp is simple, the answer is that for a string of length n, the complexity is O(n).
Is there a better way? Of course, you can see that only when 1 is added to "999...999", a carry will be generated on the basis of the first character (subscript is 0). At this time, it is the largest n-digit number. At this time, Increment returns true and the loop stops.
code show as below:

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.PrintNumber function
When the number of digits is not enough, 0 is added in front of the number, but it should not be printed when printing, so it should be printed when the first non-zero

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. Recursion makes the code more concise.
If we add 0 to the front of the number, we will find that all the decimal numbers with n digits are actually arranged from 0 to 9 in time. In other words, we arrange each digit of the number from 0 to 9, and we get all the decimal numbers. It’s just that when printing, the first 0 is not printed. The
full arrangement is easy to express. Each digit of the number can be a number from 0 to 9, and then set the next digit. When the recursive end condition is We have set the last digit of the number.

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

Reference book: "Sword Finger Offer"

Guess you like

Origin blog.csdn.net/rjszz1314/article/details/104175150