打印1到最大的n位数
2016-05-24 19:54
274 查看
题目:输入数字n,按顺序打印出1到最大的n位十进制。比如输入3,则打印出1、2、3一直到最大的三位数即999
不考虑大数:函数OnePrintOneToMaxN(int n);的功能:打印从1到最大的n位数;
但是不考虑大数是错误的;题目并没有限制n的范围,所以用int或者long long都有可能发生溢出,则需要考虑大数问题,如下函数:
考虑大数1:
函数TwoPrintOneToMaxN(int n);的功能:打印从1到最大的n位数;
函数isCreaseOneToMaxNum(char* num);的功能:用O(1)时间去判断+1后的数字是否达到最大值;
函数PrintOneToMaxNum(char* num);的功能:此数字没有达到最大的n位数就去打印;
考虑大数2(同时考虑代码的简洁,逻辑清晰):
由于考虑大数时笔试时字符串模拟数字加法代码太长,则我们希望用另外一种思路使逻辑清晰,代码简洁
数字排列(全排列)---用递归去实现,如下函数:
函数ThreePrintOneToMaxN(int n);功能:数字排列(全排列)---用递归去实现;
函数PrintDigit(char* num, int n, int index);功能:递归打印一个数字的每一位;数字的每位都从0到9排列一遍;
函数PrintOneToMaxNum(char* num);的功能:数字的每位都被设置一遍后就去打印一个数字;
代码如下:
<span style="font-size:18px;">#include<stdio.h> #include<assert.h> #include<iostream> using namespace std; //不考虑大数问题 void OnePrintOneToMaxN(int n) { if (n <= 0) { cout << "n is invalid" << endl; return; } int num = 1; int i = 0; while (i++ < n) num *= 10; for (i = 1; i < num; ++i) cout << i << " "; cout << endl; } //用O(1)时间去判断+1后的数字是否达到最大值 bool isCreaseOneToMaxNum(char* num) { assert(num); bool isOverFlow = false; int nLen = strlen(num); int CarryBehindBitAddOne = 0; for (int i = nLen - 1; i >= 0; --i) { //将个位转换为int进行+1 int BitValue = num[i] - '0' + CarryBehindBitAddOne; if (i == nLen - 1) ++BitValue; //一、+1后有进位时是否发生溢出 //1.i==0;溢出 //2.i!=0;没溢出 //二、+1后没有进位时 if (BitValue >= 10) { if (i == 0) { isOverFlow = true; } else { BitValue -= 10; CarryBehindBitAddOne = 1; num[i] = BitValue + '0'; } } else { num[i] = BitValue + '0'; break; } } return isOverFlow; } //数字没有达到最大的n位数就去打印 void PrintOneToMaxNum(char* num) { assert(num); int nLen = strlen(num); bool isZero = true; for (int i = 0; i < nLen; ++i) { //从非0数字开始打印 if (isZero && num[i] != '0') isZero = false; if (!isZero) { cout << num[i]; } } cout << " "; } //考虑大数问题-字符串模拟数字加法 void TwoPrintOneToMaxN(int n) { if (n <= 0) return; char* num = new char[n + 1]; memset(num, '0', n); num = '\0'; //只要没有超过最大的n位数就去打印数字 while (!isCreaseOneToMaxNum(num)) { PrintOneToMaxNum(num); } cout << endl; delete[] num; num = NULL; } //递归打印一个数字的每一位 void PrintDigit(char* num, int n, int index) { assert(num); if (n <= 0 && index < 0) return; //设置完每一位数字的比特位打印数字 if (index == n - 1) { PrintOneToMaxNum(num); return; } for (int i = 0; i < 10; ++i) { num[index+1] = i + '0'; PrintDigit(num, n, index + 1); } } //笔试时字符串模拟数字加法代码太长,则我们希望用另外一种思路使逻辑清晰,代码简洁 //数字排列(全排列)---用递归去实现 void ThreePrintOneToMaxN(int n) { if (n <= 0) return; char* num = new char[n + 1]; num = '\0'; for (int i = 0; i < 10; ++i) { num[0] = i + '0'; PrintDigit(num, n, 0); } cout << endl; delete[] num; } //测试用例 int main() { //不考虑大数问题 OnePrintOneToMaxN(2); cout << endl; //考虑大数问题 TwoPrintOneToMaxN(2); cout << endl; //考虑大数,同时考虑代码的简洁性,逻辑清晰 ThreePrintOneToMaxN(2); return 0; }</span>
测试结果如下图:
相关文章推荐
- Android 解决中文参数传递到服务器乱码问题
- QuickHull 快速凸包
- LoadRunner中winsocket协议学习
- iOS:Objective-C中Self和Super详解
- 一年犹太人读书64本中国人4本反映啥
- Unicode 转化 GB18030 编码 方法
- 我所知道的关于webview的知识
- C/c++语言sort函数如何使用
- ZOJ1089(dfs)
- Best Time to Buy and Sell Stock
- 图片缓存之内存缓存技术LruCache,软引用
- 方法的类型提示
- Android SERVICE后台服务进程的守护
- 工具类系列-ClazzReflectUtil
- 工具类系列-JavaBean2Map
- Cortex-A8处理器memcpy的优化方案
- Android 使用intent打开手机自带应用播放视频,音频,文档,还有打开应用市场
- 构建之法阅读笔记06
- LeetCode题解——Verify Preorder Serialization of a Binary Tree
- Android 双进程Service常驻后台,无惧“一键清理”