剑指offer 面试题12—打印1到最大的n位数

题目:

输入3,打印:1、2、3......998、999


解法一:

求出最大的n位数,然后循环从1开始逐个打印。


解答二:

解答一中当n很大时,会溢出。大数问题,用字符串解决。

申请长度为n+1的字符串,实际数字位数不够n位时,在字符串的前半部门补0。初始化全部为'0',然后每一次为字符串表示的数字加1,再打印出来。

两件事:1,在字符串表达的数字上模拟加1,2,把字符串表达的数字打印出来。


只有对“9999...99”加1的时候,才会在第一个字符(下标为0)的基础上产生进位,而其他所有情况都不会在第一个字符上产生进位。

因此当我们发现在加1时第一个字符产生了进位,则已经是最大的n位数。


打印结果的时候,要去掉前面的0,就是从第一个不为0的字符打印。


解答三:

n位所有十进制数其实就是n个从0到9的全排列。全排列用递归,数字的每一位都可能是0~9中的一个数,然后设置下一位。

递归结束的条件是我们已经设置了数字的最后一位了。


#include <iostream>
using namespace std;

//==============================方法一
void foo1(int n)
{
	int number=1;
	int i=0;
	while(i++<n)
		number*=10;

	for(i=1;i<number;i++)
		cout<<i<<" ";
	cout<<endl;
}

//==============================方法二
bool increment(char * number)
{
	bool flag=false;
	int k=0;//是否进位
	int len=strlen(number);
	for(int i=len-1;i>=0;i--)
	{
		int nSum=number[i]-'0'+k;
		if(i==len-1)
			nSum++;
		if(nSum>=10)
		{
			if(i==0)
				flag=true;
			else
			{
				nSum-=10;
				k=1;
				number[i]='0'+nSum;
			}
		}
		else
		{
			number[i]='0'+nSum;
			break;
		}
	}

	return flag;
}

void print(char * number)
{
	bool isB=true;
	int len=strlen(number);

	for(int i=0;i<len;i++)
	{
		if(isB && number[i]!='0')
			isB=false;

		if(!isB)
			cout<<number[i];
	}
	cout<<" ";
}

void foo2(int n)
{
	if(n<=0)
		return;

	char *number=new char[n+1];
	memset(number,'0',n);
	number[n]='\0';

	while(!increment(number))
	{
		print(number);
	}
	cout<<endl;

	delete [] number;
}

//==============================方法三
void digui(char *number,int len,int index)
{
	if(index==len-1)
	{
		print(number);
		return;
	}

	for(int i=0;i<10;i++)
	{
		number[index+1]=i+'0';
		digui(number,len,index+1);
	}
}

void foo3(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';
		digui(number,n,0);
	}

	delete [] number;
}

void main()
{
	int n;
	cin>>n;
	foo1(n);
	foo2(n);
	foo3(n);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值