剑指offer:面试题17--->打印1到n位数(思路解析在代码注释)

 先来读懂这道题的意思:

 下面思路都在代码注释中:

解法一:笨办法

//上图找规律  输入n = 1   输出9次:1到9
//n = 2  输出99次:1到99     
//n = 3   输出999次   1到999

void Print1toN1(int n)
{
	int num = 1;
	for(int i=0; i<n; i++)
	{
		num *= 10;  //num在此处保存需要输出的次数
	}
	//此时,num保存右边界最大值
	for(int j=1; j<num; j+=1)//再到这个for循环中依次打印出来
    {
		printf("%d ", j);
    }
}

上述这种方法会有一个问题,num值类型为int整型,所以它的取值范围为21亿多,当n的取值大于9时,他将越界,所以下面再说一种方法来扩大范围。

解法二:将打印的东西按字符进行存储,char类型的取值范围为-128~+127也就是说可以保存到127位9,比起第一张方法来说,范围大大增加。

代码实现:

void Print1toN2(int n)//用到字符串
{
	//1.申请辅助空间buff,n+1(这块+1的意义在将字符后的'\0'也加进去,所以就一次性堆区申请n+1空间)
	char *buff = (char *)malloc(sizeof(n+1));
	assert(buff != NULL);//断言

	//2.将辅助空间初始化
	memset(buff, '0', n);//将空间填充为0
	buff[n] = '\0';  //最后一位置为'\0'

	char *maxnum = (char *)malloc(sizeof(n+1));  //这块将最大值的每一位都置为9
	assert(maxnum != NULL);
	memset(maxnum, '9', n);
	maxnum[n] = '\0';

	//3.用字符数组模拟数字每次+1的变化,并打印出来 
	while(strcmp(buff, maxnum) != 0)    //这边表示字符每次加一所表示的结果
	{ 
		int sum = 0;//保存i指向位的值
		int index = 0;//进位
		for(int i=n-1; i>=0; i--)  //3   2
		{
			sum = buff[i] - '0';  //第一遍的时候   sum指向个位  第二遍十位
			sum += index;//数字获取后+进位
			if(i == n-1)//只有个位,才+1
			{
				sum = sum+1;
			}

			if(sum == 10) //个位等于10的时候,进位到十位(十位为10的时候进位,进位到百位,以此类推)
			{
				sum = sum - 10;  //进位之后个位归0
				index = 1;  
				buff[i] = sum + '0';   //加'0'就是想把int转变为char类型
			}
			else
			{
				buff[i] = sum + '0';
				break;
			}
		}
		Print_num(buff);  //该函数在下面会单独进行实现
	}

	free(buff);
	free(maxnum);
}

上述函数中Print_num函数的实现:下面函数比较简单 就不多说了

void Print_num(char *buff)
{
	int len = strlen(buff);
	char *p = buff;
	while(*p != '\0')
	{
		if(*p == '0')
		{
			p++;
		}
		else
		{
			break;
		}
	}

	printf("%s ", p);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值