题目:输入数字n,按顺序打印出从1最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数即999。
最容易想到的办法是先求出最大的n位数,然后用一个循环从1开始逐个打印:
static void Print1ToMaxOfNDigitsSimple(int n)
{
int number = 1;
int i = 0;
while (i < n)
{
number = number * 10;
i++;
}
for (i = 1; i < number; i++)
{
Console.Write("{0}\t", i);
}
}
初看之下好像没有问题,但是其并没有考虑大数问题,有可能即使用整型(int)或长整型(long)都会溢出。
解决这个问题需要表达一个大数。最常用也是最容易的方法是用字符串或者数组表达大数。该算法的步骤如下:
Step1.把字符串中的每一个数字都初始化为'0';
Step2.每一次为字符串表示的数字加1,再打印出来;
static void Print1ToMaxOfNDigits(int n)
{
if (n <= 0)
{
return;
}
// memset(number,'0',n);
char[] number = new char[n + 1];
for (int i = 0; i < n; i++)
{
number[i] = '0';
}
number[n] = '\0';
// Increment实现在表示数字的字符串number上增加1
while (!Increment(number))
{
// PrintNumber负责打印出number
PrintNumber(number);
}
number = null;
}
static bool Increment(char[] number)
{
bool isOverflow = false;
int takeOver = 0;
int length = number.Length - 1;
for (int i = length - 1; i >= 0; i--)
{
int sum = number[i] - '0' + takeOver;
if (i == length - 1)
{
sum++;
}
if (sum >= 10)
{
if (i == 0)
{
// 标识已经溢出了
isOverflow = true;
}
else
{
sum -= 10;
takeOver = 1;
number[i] = (char)('0' + sum);
}
}
else
{
number[i] = (char)('0' + sum);
break;
}
}
return isOverflow;
}
static void PrintNumber(char[] number)
{
bool isBeginning0 = true;
for (int i = 0; i < number.Length; i++)
{
if (isBeginning0 && number[i] != '0')
{
isBeginning0 = false;
}
if (!isBeginning0)
{
Console.Write("{0}", number[i]);
}
}
Console.Write("\t");
}
这里要注意的是:当数字不够n位的时候,我们在数字的前面补0,打印的时候这些补位的0不应该打印出来。
static void PrintTest(int n)
{
Console.WriteLine("Test for {0} begins:", n);
Print1ToMaxOfNDigits(n);
Console.WriteLine("Test for {0} ends.", n);
}
static void Main(string[] args)
{
PrintTest(1);
PrintTest(2);
PrintTest(3);
PrintTest(0);
PrintTest(-1);
Console.ReadKey();
}
作者:周旭龙
出处:http://edisonchou.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。