面试题12:打印1到最大的n位数
2016-06-22 20:47
477 查看
1. 如果考虑到n很大的话,n位数的表示可能超出了计算机的表示范围,所以就算是定义为long long也不行,这是大数问题,通常可以用字符串或者是数组来表示,可以用字符串来存储整数的每一位,应为每一位的大小都不会超过9,可以表示。可以在字符串中模拟加法和进位来实现打印数字。要注意的点就是加法加到最高位的时候要判断进位溢出,打印的时候高位是0的话,可以不用打印。
源码:
#include <iostream>
#include<cstdio>
#include <memory>
using namespace std;
void PrintNumber(char* number);
bool Increment(char* number);
void Print1ToMaxOfNDigitsRecursively(char* number, int length, int index);
// ====================方法一 模拟加法的方法====================
void Print1ToMaxOfNDigits_1(int n)
{
if (n <= 0)
return;
char *number = new char[n + 1];
memset(number, '0', n);
number
= '\0';
while (!Increment(number))
{
PrintNumber(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--)
{
int nSum = number[i] - '0' + nTakeOver;
if (i == nLength - 1)
nSum++;
if (nSum >= 10) //产生进位的情况
{
if (i == 0)//最高位产生进位的情况
isOverflow = true;
else //不是最高位产生的进位,然后置0,进位标志置为1,
{
nSum -= 10;
nTakeOver = 1;
number[i] = '0' + nSum;
}
}
else
{
number[i] = '0' + nSum;//没有产生进位的情况,实际上只是最低位在加一,高位没有变化
break;
}
}
return isOverflow;
}
// ====================方法二- 递归全排列的方法====================
void Print1ToMaxOfNDigits_2(int n)
{
if (n <= 0)
return;
char* number = new char[n + 1];
number
= '\0';
for (int i = 0; i < 10; ++i)
{
number[0] = i + '0';
Print1ToMaxOfNDigitsRecursively(number, n, 0);
}
delete[] number;
}
void Print1ToMaxOfNDigitsRecursively(char* number, int length, int index)
{
if (index == length - 1)
{
PrintNumber(number);
return;
}
for (int i = 0; i < 10; ++i)
{
number[index + 1] = i + '0';
Print1ToMaxOfNDigitsRecursively(number, length, index + 1);
}
}
// 打印出字符串,高位的0不会打印
void PrintNumber(char* number)
{
bool isBeginning0 = true;
int nLength = strlen(number);
for (int i = 0; i < nLength; ++i)
{
if (isBeginning0 && number[i] != '0')//从左到右,如果碰到第一个非零的值,则后面的值都会被打印
isBeginning0 = false;
if (!isBeginning0)
{
printf("%c", number[i]);
}
}
printf("\t");
}
int main()
{
printf("first method :\n");
Print1ToMaxOfNDigits_1(2);
printf("\nsecond method :\n");
Print1ToMaxOfNDigits_2(2);
system("PAUSE");
return 0;
}
结果:
源码:
#include <iostream>
#include<cstdio>
#include <memory>
using namespace std;
void PrintNumber(char* number);
bool Increment(char* number);
void Print1ToMaxOfNDigitsRecursively(char* number, int length, int index);
// ====================方法一 模拟加法的方法====================
void Print1ToMaxOfNDigits_1(int n)
{
if (n <= 0)
return;
char *number = new char[n + 1];
memset(number, '0', n);
number
= '\0';
while (!Increment(number))
{
PrintNumber(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--)
{
int nSum = number[i] - '0' + nTakeOver;
if (i == nLength - 1)
nSum++;
if (nSum >= 10) //产生进位的情况
{
if (i == 0)//最高位产生进位的情况
isOverflow = true;
else //不是最高位产生的进位,然后置0,进位标志置为1,
{
nSum -= 10;
nTakeOver = 1;
number[i] = '0' + nSum;
}
}
else
{
number[i] = '0' + nSum;//没有产生进位的情况,实际上只是最低位在加一,高位没有变化
break;
}
}
return isOverflow;
}
// ====================方法二- 递归全排列的方法====================
void Print1ToMaxOfNDigits_2(int n)
{
if (n <= 0)
return;
char* number = new char[n + 1];
number
= '\0';
for (int i = 0; i < 10; ++i)
{
number[0] = i + '0';
Print1ToMaxOfNDigitsRecursively(number, n, 0);
}
delete[] number;
}
void Print1ToMaxOfNDigitsRecursively(char* number, int length, int index)
{
if (index == length - 1)
{
PrintNumber(number);
return;
}
for (int i = 0; i < 10; ++i)
{
number[index + 1] = i + '0';
Print1ToMaxOfNDigitsRecursively(number, length, index + 1);
}
}
// 打印出字符串,高位的0不会打印
void PrintNumber(char* number)
{
bool isBeginning0 = true;
int nLength = strlen(number);
for (int i = 0; i < nLength; ++i)
{
if (isBeginning0 && number[i] != '0')//从左到右,如果碰到第一个非零的值,则后面的值都会被打印
isBeginning0 = false;
if (!isBeginning0)
{
printf("%c", number[i]);
}
}
printf("\t");
}
int main()
{
printf("first method :\n");
Print1ToMaxOfNDigits_1(2);
printf("\nsecond method :\n");
Print1ToMaxOfNDigits_2(2);
system("PAUSE");
return 0;
}
结果:
相关文章推荐
- 剑指offer阅读笔记 之面试题19 实现二叉树的镜像 之 又复习一遍二叉树
- 优秀程序员的博客有哪些?(转)
- 程序员写博客这件小事
- Mac开发利器之程序员编辑器MacVim学习总结(转)
- iOS面试题
- 前端面试题之Html和CSS
- 一道JS面试题
- JAVA程序员必看的15本书-JAVA自学书籍推荐
- 给职场新人的提升建议
- 面试题
- 小谈面试时面试官为什么问ArrayList,LinkedList与List的不同
- iOS面试题总结(一)
- k&S公司笔试和面试
- 这些职场族群中,有你吗?
- 前端开发面试题(一)
- 简单所以不要忽视,关于\r\n和\n程序员应了解的实际应用
- 华为的java面试题
- 算法面试题(二)-- 最长公共子序列(LCS)与苦恼的月下老人
- 程序员必知的七个图形工具
- 混日子不是你的错,根源在这