首页 > 编程语言 >Java 剑指offer(16) 打印1到最大的n位数

Java 剑指offer(16) 打印1到最大的n位数

时间:2023-03-12 11:34:34浏览次数:53  
标签:digit Java offer int 打印 number char 16 test

题目

输入数字n,按顺序打印出从1最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数即999。

思路

陷阱: n过大时是大数问题,不能简单用int或者long数据输出,需要采用字符串或者数组表达大数。

解决方法: 通过字符数组char[]来进行输出数字。

方法一:

1)在字符串表达的数字上模拟加法;

2)把字符串表达的数字打印出来。

方法二:

1)采用递归将每一位都从0到9排列出来;

2)把字符串表达的数字打印出来。

·测试算例

功能测试(输入1,2,3……)

特殊输入测试(输入0,-1)

完整Java代码

自己复习时写的方法(比第一次写的方法更清晰、简洁点):

	public void print1ToMaxOfNDights1s(int n) {
		if(n<=0)
			return;
		char[] digit = new char[n];
		for(int i=0;i<n;i++)
			digit[i]='0';
		for(int i=n-1;i>=0;i--) {
			while(digit[i]!='9') {
				int m=0;
				digit[m]++;
				while(m<n-1 && digit[m]>'9') {
					digit[m]='0';
					digit[m+1]++;
					m++;
				}
				printdigits(digit);
			}
		}
	}

	private void printdigits(char[] digit) {
		int m = digit.length-1;
		while(digit[m]=='0')
			m--;
		for(int i=m;i>=0;i--)
			System.out.print(digit[i]);
		System.out.println();
	}

(第一次写的代码,含测试)

/**
 * 
 * @Description 面试题17:打印1到最大的n位数
 *
 * @author yongh
 * @date 2018年9月17日 下午9:07:53
 */

// 题目:输入数字n,按顺序打印出从1最大的n位十进制数。比如输入3,则
// 打印出1、2、3一直到最大的3位数即999。

public class Print1ToMaxOfNDigits {
	
	//=========方法一============
	/**
	 * 采用模拟加一的方法
	 */
	public void print1ToMaxOfNDigits(int n) {
		if (n <= 0)
			return;
		char[] number = new char[n];
		// 不能用foreach方法对nuber[]赋值
		// for (char c : number) {
		// c = '0';
		// }
		for (int k = 0; k < number.length; k++)
			number[k] = '0';
		while (!increment(number)) {
			printCharNumber(number);
		}
	}	
	
	/**
	 * 对字符串进行加一操作,number达到最大值后返回true
	 * 最低位加一;所有位如果超过10,则进位
	 */
	private boolean increment(char[] number) {
		int nTakeOver = 0; // 代表进位
		for (int i = number.length - 1; i >= 0; i--) {
			int nSum = (number[i] - '0') + nTakeOver; // 当前位置数字
			// number[i]-'0'是把char转化为int,nTakeOver代表进位
			if (i == number.length - 1)
				nSum++;
			if (nSum >= 10) {
				if (i == 0)
					return true; // 超出范围了
				nTakeOver = 1;
				nSum -= 10;
				number[i] = (char) (nSum + '0');
			} else {
				number[i] = (char) (nSum + '0');
				break; // 高位不变,可以直接跳出循环了
			}
		}
		return false;
	}

	/**
	 * 打印字符数组形成的数字
	 * 书中方法:利用布尔变量isBeginning0来从第一个非零字符打印
	 */
	private void printCharNumber(char[] number) {
		boolean isBeginning0 = true;
		for (int i = 0; i < number.length; i++) {
			if (isBeginning0 && (number[i] - '0') != 0) {
				isBeginning0 = false;
			}
			if (!isBeginning0) {
				// System.out.print(number[i] - '0');
				System.out.print(number[i]);
			}
		}
		System.out.println();

	}

	/**
	 * 打印字符数组形成的数字
	 * 自己的方法:找出第一个非零字符位置,往后进行打印
	 */
	private void printCharNumber2(char[] number) {
		int beginner = number.length; // 不写成number.length-1,以防写出0
		for (int i = 0; i <= number.length - 1; i++) {
			if ((number[i] - '0') != 0) {
				beginner = i;
				break;
			}
		}
		for (int i = beginner; i <= number.length - 1; i++) {
			System.out.print(number[i]);
		}
		if (beginner != number.length) // 数字为0时,换行符不输出
			System.out.println();
	}

	
	//=========方法二============
	/**
	 * 采用递归的方法
	 */
	public void print1ToMaxOfNDigits2(int n) {
		if (n <= 0)
			return;
		char[] number = new char[n];
		for (int k = 0; k < number.length; k++)
			number[k] = '0';
		for (int i = 0; i <= 9; i++) {
			makeNumber(n, number, i, 0);
		}
	}

	/**
	 * 生成数字
	 */
	private void makeNumber(int n, char[] number, int nNumber, int index) {
		if (index == number.length - 1) {
			number[index] = (char) (nNumber + '0');
			printCharNumber2(number); // 打印数字代码与第一个方法一样
			return;
		} else {
			number[index] = (char) (nNumber + '0');
			for (int i = 0; i <= 9; i++) {
				makeNumber(n, number, i, index + 1);
			}
		}
	}

	// ========测试代码=============
	void test(int nDigits) {
		System.out.println("===test begin===");
		System.out.println("method1:");
		print1ToMaxOfNDigits(nDigits);
		System.out.println("method2:");
		print1ToMaxOfNDigits2(nDigits);
		System.out.println("===test over===");
	}

	public static void main(String[] args) {
		Print1ToMaxOfNDigits demo = new Print1ToMaxOfNDigits();
		demo.test(-1);
		demo.test(0);
		demo.test(1);
		demo.test(2);
	}
}

===test begin===
method1:
method2:
===test over===
===test begin===
method1:
method2:
===test over===
===test begin===
method1:
1
2
3
4
5
6
7
8
9
method2:
1
2
3
4
5
6
7
8
9
===test over===
===test begin===
method1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
method2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
===test over===

Print1ToMaxOfNDigits

收获

1.任何时候都不能轻视题目,像这道题看起来简单,但其实涉及到大数问题,以后遇到数字相关的题目时要注意大数问题;

2.int类型和char类型转化,通过±‘0’来实现,int与char类型间的相互转换:https://www.cnblogs.com/yongh/p/9688259.html。

3.打印字符串表示的数组,从第一个非零数字打印。

标签:digit,Java,offer,int,打印,number,char,16,test
From: https://www.cnblogs.com/gdutxiaoxu/p/17207842.html

相关文章

  • Java中的保留字
    下面是Java中的保留字及其含义:保留字含义abstract抽象类或抽象方法assert断言条件为真boolean布尔类型break跳出循环或switch语句byte8位带符号整......
  • Java 建造者模式/链式调用 简单Demo
    最近,公司同事要求我给他们讲一下RxJava,为了更清晰的说明其架构,.简单写了一个链式调用的小Demo,分享给大家/**作者:赵星海(CSDN-深海呐)*时间:2019年3月19日16:56:32*......
  • Java 关于单例模式(懒汉式与饿汉式的区别)
             Java关于单例模式(懒汉式与饿汉式的区别)简单说下两个单例模式的不同点懒汉式:1.内部对象非final类型2.线程安全3.用到特定方法的时候才会实例......
  • Java 一行代码判断String字符串是否为纯符号
                 一行代码判断String字符串是否为纯符号 最近项目中新加的需求我感觉我的构思很好,分享给大家原理:1.将String去除前后空格2.将Str......
  • Java 判断String字符串是否是中文
    判断String字符串是否是中文Stringstring;//需要判断的内容if(string.matches("[\u4E00-\u9FA5]+")){ToastUtils.Toast(Activity_authentication.this,"内容是中文")......
  • Java 自定义提取字符串中的某一段字符
                     自定义String过滤举例:Strings="dsadsada<@#$@#$>啦啦啦123123<&*&*&*>"要去除所有尖括号里的内容得到结果 "dsa......
  • Android与H5(JavaScript)之间的简单交互
    Android响应Js的动作 假设网页端要调用Android原生的方法:showToast();1.做一个盆子接收消息(创建一个工具类,写一个方法(*带注解))publicclassJavaScriptMethod{......
  • java动态代理和CGLIB
    参考:https://www.jianshu.com/p/cbd4c1ad8a75上一篇我们利用jdk的动态代理实现了一个简单的注解处理器,可以自动给一个button添加指定的监听器.但是jdk的动态代理有一个......
  • Java基础四-异常处理/集合框架以及泛型
    异常的处理编写程序时,代码可能会重新啊运行错误或编译错误,为了处理问题可以使用异常机制异常包括错误类型,原因和位置异常的体系结构 如何进行异常处理java异常......
  • Java 分支结构——if-else(一)
    基本语法结构1:单分支条件判断:if格式:if(条件表达式){语句块;}说明:条件表达式必须是布尔表达式(关系表达式或逻辑表达式)或布尔变量。执行流程:首先判断条件表......