题目描述
输入数字n,按顺序打印出1到最大的n位十进制数,比如输入3,则打印1,2,3一直到最大的3位数即999
思路:看似很简单的一道题:
public static void Print1ToMaxOfDigits(int n){
int number=1;
for(int i=0;i<n;i++){
number=number*10;
}
for(int j=1;j<number;j++){
System.out.println(j);
//上述代码存在问题,若n比较大,number可能会溢出,所以应考虑用字符串或者数组来存储
}
先给出代码:
package com.su.biancheng;
import java.util.Arrays;
/**
* @title Print1ToMaxOfDigits.java
* @author Shuai
* @date 2016-4-9下午4:22:24
*/
public class Print1ToMaxOfDigits {
public static void Print1ToMaxOfDigits(int n){
/*
int number=1;
for(int i=0;i<n;i++){
number=number*10;
}
for(int j=1;j<number;j++){
System.out.println(j);
}
*/
//上述代码存在问题,若n比较大,number可能会溢出,所以应考虑用字符串或者数组来存储
if(n<=0)
return;
char[] number=new char[n];
//初始化每个字符都为'0'
for(int i=0;i<number.length;i++){
number[i]='0';
}
while(!Increment(number)){
PrintNumer(number);
}
//System.out.println(number);
}
private static void PrintNumer(char[] number) {
//从第一个不为'0'开始打印
boolean isBeginning0=true;
for(int i=0;i<number.length;i++){
if(isBeginning0&&number[i]!='0'){
isBeginning0=false;
}
if(!isBeginning0){
System.out.print(number[i]);
}
}
System.out.println();
}
private static boolean Increment(char[] number) {
boolean isOverFlow=false;
int iTakeOver=0;
for(int i=number.length-1;i>=0;i--){
int iSum=number[i]-'0'+iTakeOver;
if(i==number.length-1){
iSum++;//如果是0999...999,加1,最高位由'0'变为1,据此可判断是否已经加到最大值
}
if(iSum>=10){
if(i==0){
isOverFlow=true;
//break;可加可不加,因为此时已经循环结束
}
else{
iSum-=10;
iTakeOver=1;
number[i]=(char) ('0'+iSum);
}
}
else{
number[i]=(char) ('0'+iSum);
break;
}
}
return isOverFlow;
}
public static void main(String[] args){
int n=3;
Print1ToMaxOfDigits(n);
}
}
Note:
while(!Increment(number)){
PrintNumer(number);
}
解释一下以上代码,它的作用是为了检查是否已经加到最大数字。
Increment(number)
为什么不直接调用字符串比较函数equal来判断是否已经到99..99?
因为equal函数要逐个比较,对于n位数,时间为O(n),加上外层循环while,时间为O(n^2)
能否O(1)时间内完成比较?
如果已经是最大数字,则加上1后:最高位变为0(数组的第一位),同时产生数组越界的标志(就是进位了,这里字符数组长度为)
PrintNumer(number);
为什么不直接使用System.out.println(number);
使用System.out.println(number);则打印出的格式是00..01,00..02,..,不符合习惯。所以希望把没用的前面的0去掉。
每个数都是字符数组存储的,我们想从前往后遍历,找到第一个不为0,然后开始打印即可。
思路二:数字排列
算上需要前面补0的,n位数每一位都是0-9排列,这样可以使用递归的思想,先构造第一位,然后构造下一位,当构造到n位时,打印输出
/**
*
*/
package com.su.biancheng;
/**
* @title Print1ToMaxOFDigits2.java
* @author Shuai
* @date 2016-4-9下午7:50:15
*/
public class Print1ToMaxOFDigits2 {
public static void Print1ToMaxOFDigits2(int n){
if(n<=0)
return;
char[] number=new char[n];
/*for(int i=0;i<number.length;i++){
number[i]='0';
}*/
Print1ToMaxOFDigitsRecursively(number,n,0);
}
private static void Print1ToMaxOFDigitsRecursively(char[] number, int n,
int index) {
if(index==number.length){
PrintNumber(number);
return;
}
for(int i=0;i<10;i++){
number[index]=(char) (i+'0');
Print1ToMaxOFDigitsRecursively(number,n,index+1);
}
}
private static void PrintNumber(char[] number) {
boolean isBeginning0=true;
for(int i=0;i<number.length;i++){
if(isBeginning0&&number[i]!='0'){
isBeginning0=false;
}
if(!isBeginning0){
System.out.print(number[i]);
}
}
if(!isBeginning0){//00.000,不需要打印
System.out.println();
}
}
public static void main(String[] args){
int n=3;
Print1ToMaxOFDigits2(n);
}
}