題目:輸入數字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);
}
}
擴展題大數加法等實現了在補充,現在卡在加負數上面。