题目:打印从1~最大的n位数

分析:知道陷阱在哪,即n很大时若用通常的int,long会溢出;想到用字符串解决,这涉及到字符转数字及反过来。

  刚开始纠结于字符串怎么加1,想了片刻,觉得应该取出最后一位上的字符,转成数字+1再转成字符,但这就出现个问题:'9'加1后得到'10',这会产生进位。。。

  到这思维就乱了。。。1、不断向前进位怎么解决?2、怎么判断到达最大值?

在看过作者的代码后才豁然开朗。。。,解决方案:1、将进位与不进位分开,并且进位时设定nTakeOver用于下一字符的加,该过程用循环完成;2、同样判断最大值时,若第一位的数值=10了,那肯定已经到达最大值了

结合参考代码,自己所写代码如下:

#include "stdafx.h"
#include <iostream> using namespace std; void PrintNumber(char* number); //打印数字
bool Increment(char* number,int length); //加1 // ====================方法一====================
void Print1ToMaxOfNDigits_1(int n)
{
if(n <= )
return; //错误处理 char *number = new char[n + ];
memset(number, '', n); //memset()函数设置number的前n位为字符‘0’:memset(number,'0',n); 该函数位于<memory>
number[n] = '\0'; //注意字符串以‘/0’结尾!!! while(!Increment(number,n))
{
PrintNumber(number);
} //加1成功则打印 delete [] number;
} //实现加1操作
//一直到某位上的数值不超过9,终止循环
//利用循环向前进位
bool Increment(char* number, int length)
{
bool isOverFlow = false;
int nTakeOver = ;
for(int i=length-; i>=; i--)
{
//加1,要考虑之前的进位nTakeOver
int num_value = number[i] - '' + nTakeOver;
if(i == length-)
num_value += ;
if(num_value <= )
{
number[i] = num_value + '';
break;
}
else
{
//达到最大n位数后终止
if(i == )
isOverFlow = true;
else
{
nTakeOver = ;
number[i] = num_value - + '';
}
}
} return isOverFlow;
} //打印字符串表示的数字
void PrintNumber(char* number)
{
while(*number != '\0')
{
if(*number == '')
number++;
else
{
cout<<number<<'\t';
break;
}
}
} // ====================测试代码====================
void Test(int n)
{
printf("Test for %d begins:\n", n); Print1ToMaxOfNDigits_1(n); printf("Test for %d ends.\n", n);
} int main()
{
Test();
Test();
Test();
Test();
Test(-); return ;
}

说明:只是在PrintNumber子函数上做了些改进。

另一种思路:因为每位为0~9,共n位,所以数字个数=10^n-1,因此相当于全排列的方法,而全排列可用递归实现

这种方法由于涉及到递归,所以自己很难想到,即便想到也很难写出来。。。

参考代码如下:

// ====================方法二====================
void Print1ToMaxOfNDigits_2(int n)
{
if(n <= )
return; char* number = new char[n + ];
number[n] = '\0'; for(int i = ; i < ; ++i)
{
number[] = i + '';
Print1ToMaxOfNDigitsRecursively(number, n, );
} delete[] number;
} void Print1ToMaxOfNDigitsRecursively(char* number, int length, int index)
{
if(index == length - )
{
PrintNumber(number);
return;
} for(int i = ; i < ; ++i)
{
number[index + ] = i + '';
Print1ToMaxOfNDigitsRecursively(number, length, index + );
}
}

简单明了!!!

PS:对全排列的递归实现,值得关注与记忆!!!

剑指offer--面试题12的更多相关文章

  1. 剑指Offer:面试题12——打印1到最大的n位数(java实现)

    问题描述: 输入数字n,按顺序打印出从1到最大的n位十进制数,比如输入3,则打印出1,2,3一直到最大的3位数即999. 思路1:最简单的想法就是先找出最大的n位数,然后循环打印即可. public ...

  2. 【剑指offer 面试题12】打印1到最大的n位数

    思路: 用n位字符数组表示n位数,通过递归的方式逐层(位)遍历,递归终止时打印. #include "stdio.h" #include "string.h" ...

  3. 剑指Offer——笔试题+知识点总结

    剑指Offer--笔试题+知识点总结 情景回顾 时间:2016.9.23 12:00-14:00 19:00-21:00 地点:山东省网络环境智能计算技术重点实验室 事件:笔试 注意事项:要有大局观, ...

  4. C++版 - 剑指Offer 面试题39:二叉树的深度(高度)(二叉树深度优先遍历dfs的应用) 题解

    剑指Offer 面试题39:二叉树的深度(高度) 题目:输入一棵二叉树的根结点,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度.例如:输入二叉树 ...

  5. C++版 - 剑指Offer 面试题45:圆圈中最后剩下的数字(约瑟夫环问题,ZOJ 1088:System Overload类似)题解

    剑指Offer 面试题45:圆圈中最后剩下的数字(约瑟夫环问题) 原书题目:0, 1, - , n-1 这n个数字排成一个圈圈,从数字0开始每次从圆圏里删除第m个数字.求出这个圈圈里剩下的最后一个数字 ...

  6. 【剑指Offer面试题】 九度OJ1368:二叉树中和为某一值的路径

    题目链接地址: http://ac.jobdu.com/problem.php? pid=1368 题目1368:二叉树中和为某一值的路径 时间限制:1 秒内存限制:32 兆特殊判题:否提交:2252 ...

  7. 【剑指Offer面试题】九度OJ1384:二维数组中的查找

    下决心AC全部剑指offer面试题. 九度OJ面试题地址:http://ac.jobdu.com/hhtproblems.php 书籍:何海涛--<剑指Offer:名企面试官精讲典型编程题> ...

  8. 剑指Offer:面试题15——链表中倒数第k个结点(java实现)

    问题描述 输入一个链表,输出该链表中倒数第k个结点.(尾结点是倒数第一个) 结点定义如下: public class ListNode { int val; ListNode next = null; ...

  9. 剑指offer面试题3 二维数组中的查找(c)

    剑指offer面试题三:

  10. C++版 - 剑指offer之面试题37:两个链表的第一个公共结点[LeetCode 160] 解题报告

    剑指offer之面试题37 两个链表的第一个公共结点 提交网址: http://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?t ...

随机推荐

  1. windows下部署 ISCSI存储

    Write bt xiaoyang 配置篇 这里使用的软件为iscsiTargetqfe 1.      首先安装软件,可在微软官网下载 2.      然后找到安装程序 3.      完成安装后打 ...

  2. Linux下DNS服务器的基本搭建

    技术交流群:286866978 安装与配置 1. 装载光驱 2. 卸载光驱 3. 将安装包放在合适的文件夹并解压(有的更换光盘需要重新装载) 4. 安装 5. 重定向配置文件 6. 配置named.c ...

  3. 【转】 memwatch使用说明书

    memwatch使用说明书 1.memwatch是什么?    memwatch是C语言的内存检测器.除了检测内存的功能外,它同样可以做其它的一些事情,而我们主要还是在于讲述它的基本功能.如果你真的想 ...

  4. daily news新闻阅读客户端应用源码(兼容iPhone和iPad)

    daily news新闻阅读客户端应用源码(兼容iPhone和iPad),也是一款兼容性较好的应用,可以支iphone和ipad的阅读阅读器源码,设计风格和排列效果很不错,现在做新闻资讯客户端的朋友可 ...

  5. 比较不错的一个ios找茬游戏源码

    找茬游戏源码 ,这个是一款非常不错的ios找茬游戏源码,该游戏的兼容性非常好的,并且还可以支持ipad和iphone,UI界面设计得也很漂亮,游戏源码真的是一款非常完美,而且又很完整的一款休闲类的游戏 ...

  6. sql临时表和表变量

    1. 为什么要使用表变量 表变量是从2000开始引入的,微软认为与本地临时表相比,表变量具有如下优点:  a.与其他变量的定义一样,表变量具有良好的定义范围,并会被自动清除:  b.在存储过程中使用表 ...

  7. js----方法是否加括号的问题

    在我们js编写程序的时候,我们会写很多函数然后调用它们,那么这些函数调用的时候什么时候加()什么时候不加()?记住以下几个要点. (1)函数做参数时都不要括号. function fun(e) { a ...

  8. linux 终端显示 -bash-4.1

    解决方法: cp /etc/skel/.bashrc /root/ cp /etc/skel/.bash_profile  /root/ 重新登陆就OK了

  9. jdbc连接数据库使用sid和service_name的区别

    问题描述: ORA-12505, TNS:listener does not currently know of SID given in connect descriptor The Connect ...

  10. Linq中延迟查询和立即查询

    //立即查询 public static void NowExecute() { var results = new int[]{5,4,3,2,1,6,7,8,9,0 }; int i = 0; v ...