剑指offer_12_打印1到最大的n位数
题目:输入数字n,按顺序打印出1到最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数即999。
显然,这里面有一个小陷阱,当我们输入的n很大时,就算我们用长整形(long long)都会溢出。long int 最大值为2^64 -1,约二十位。也就是说当输入的n大于20是就会产生溢出。我们就需要考虑到这是一个大数问题。
最常用的方法是用字符串或数组表示大数。
用字符串表示数字的时候,最直观的方法就是字符串里每个字符都是 '0' 到 '9' 之间的某一个字符,用来表示数字中的一位。因为数字最大的时候n位的,因此我们需要一个长度为n+1的字符串(字符串中最后一个是结束符号 '\0' )。当实际数字不够n位时,在字符串的前半部分补0。
void Print1ToNDigits(int n)
{
if(n<0)
return;
char *number = new char[n+1];
memset(number, '0', n);
number[n] = '\0';
while(!Increment(number))
{
PrintNumber(number);
//printf("%s \n",number);
}
delete []number;
}
在字符串模拟加一
bool Increment(char* number)
{
//溢出判定
bool isOverFlow = false;
//进位
int nTakeOver = 0;
//长度
int nLength = strlen(number);
for(int i = nLength - 1; i >= 0; i--)
{
//第n位的值等于第n位字母的ascii减去 0 的ascii 再加第n+1位的进位
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;
}
打印字符串表示的数字
void PrintNumber(char* number)
{
bool isBegining0 = true;
int nLength = strlen(number);
for(int i = 0; i< nLength; ++i)
{
if(isBegining0 && number[i] != '0')
isBegining0 = false;
if(!isBegining0)
{
printf("%c",number[i]);
}
}
printf("\t");
}
全部代码:
//字符串模拟数字
#include<stdio.h>
#include<stdlib.h>
#include <algorithm>
using namespace std;
#define type char
bool Increment(char*);
void PrintNumber(char*);
void Print1ToNDigits(int);
void main(){
//输出到文件
//freopen("output.txt","w",stdout);
Print1ToNDigits(5);
}
void Print1ToNDigits(int n)
{
if(n<0)
return;
char *number = new char[n+1];
memset(number, '0', n);
number[n] = '\0';
while(!Increment(number))
{
PrintNumber(number);
//printf("%s \n",number);
}
delete []number;
}
//字符串模拟加法
bool Increment(char* number)
{
//溢出判定
bool isOverFlow = false;
//进位
int nTakeOver = 0;
//长度
int nLength = strlen(number);
for(int i = nLength - 1; i >= 0; i--)
{
//第n位的值等于第n位字母的ascii减去 0 的ascii 再加第n+1位的进位
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;
}
//打印字符串表示的数字
void PrintNumber(char* number)
{
bool isBegining0 = true;
int nLength = strlen(number);
for(int i = 0; i< nLength; ++i)
{
if(isBegining0 && number[i] != '0')
isBegining0 = false;
if(!isBegining0)
{
printf("%c",number[i]);
}
}
printf("\t");
}