劍指Offer_面試題12_打印1到最大的n位數

題目:輸入數字n,按順序打印出從1到最大的n位十進制數。比如輸入3,則打印1、2、3一直到最大的3位數即999。

陷阱:這個題目看似簡單,我們先求出最大的n位數,然後for循環從1開始打印。

void PrintToMax(int n)
{
    int number = i;
    int i = 0;
    while(i++ < 10)
        number *= 10;

    for(i = 1; i < number; ++i)
        printf("%d\t", i);
}
乍看沒啥毛病,但如果仔細分析會發現面試官並沒有指定n的範圍。當n輸入很大的時候,最大的n位數用int或者long long會不會都要溢出?這也就是要考慮大數問題。陷阱,赤果果的陷阱。


民工解法:模擬字符串加法,繞過陷阱。爲了保存n爲數字我們需要一個n+1長度的字符串,且初始化爲'0',末尾置爲'\0'。主要完成兩個功能:模擬加法、打印數字。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
bool Increment(char *number)
{
	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)    //判段加到最大數值了。此時number已經修改,但不打印最後一個“越界的數值”
				return true;
			else
			{
				nSum -= 10;
				nTakeOver = 1;
				number[i] = '0' + nSum;
			}
		}
		else
		{
			number[i] = '0' + nSum;
			break;
		}
	}
	return false;
}

void PrintNumber(char *number)
{
	while (*number == '0')
	{
		number++;
	}
	printf("%s\t", number);
}

民工解法2:遞歸,數字全排列  n位所有十進制數字其實都是n個從0到9的全排列,也就是說把每一位從0到9排列一遍,就能得到所有十進制數。

void Print(char *number)   //輸出字符串  
{
	while (*number == '0')
	{
		number++;
	}
	printf("%s ", number);
}

void PrintRecur(char *number, int n, int index)  //全排列的方式  
{
	int i = 0;
	if (index == n)     //從最後一個字符開始排列,如果排列到第一個字符就打印出來  
	{
		Print(number);
		return;
	}
	for (i = 0; i<10; i++)
	{
		number[index] = i + '0';   //控制這個字符串中的每個字符從0~9的變化  
		PrintRecur(number, n, index + 1);
	}
}
擴展題大數加法等實現了在補充,現在卡在加負數上面。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章