java学习中小tips

整理

1. 分离数位

1.1 求数位和(P66 4.8)

题目:输入一个整数,求其各位数字之和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.util.Scanner;

public class DigitSumSimple {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入一个整数:");
int n = Math.abs(scanner.nextInt()); // 直接取绝对值

int sum = 0;
while (n > 0) {
sum += n % 10;
n /= 10;
}

System.out.println("各位数字之和为:" + sum);
scanner.close();
}
}

1.2 数字反转

题目:输入一个整数,输出其反转后的数
样例:输入123,输出321

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.util.Scanner;

public class ReverseNumber {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入一个整数:");
int n = scanner.nextInt();
int reversed = 0;

while (n > 0) {
int digit = n % 10;
reversed = reversed * 10 + digit;
n /= 10;
}
System.out.println("反转后的数字:" + reversed);
scanner.close();
}
}

1.3 判断回文数

题目:输入一个数,判断是否是回文数(正着读和倒着读相等的数)
输出要求:如果是回文数输出”yes”,否则输出”no”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.util.Scanner;

public class PalindromeCheckerSimple {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();

if (n < 0) {
System.out.println("no");
} else {
int original = n;
int reversed = 0;

while (n > 0) {
reversed = reversed * 10 + n % 10;
n /= 10;
}

System.out.println(reversed == original ? "yes" : "no");
}

scanner.close();
}
}

回文数规律简短总结

  • 通用模式:数字序列中心对称
  • 具体规律:
    • 3位:ABA模式(首尾相同)
    • 4位:ABBA模式(首尾相同,中间两位相同)
    • 5位:ABCBA模式(首尾相同,次位与倒数第二位相同)
    • 6位:ABCCBA模式(首尾相同,次位与倒数第二位相同,中间两位相同)
    • 7位:ABCDCBA模式(首尾相同,次位与倒数第二位相同,第三位与倒数第三位相同)
  • 核心特点:
    • 奇数位:中间数字任意
    • 偶数位:完全对称
  • 判断方法:比较第i位与第(n-i+1)位是否相等(i从1开始)
  • 最简判断:数字反转后等于原数就是回文数

2. 自幂数

2.1 判断水仙花数

题目:输入一个三位数,判断是否满足 ABC = A³ + B³ + C³
输出要求:如果是水仙花数输出”yes”,否则输出”no”

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
import java.util.Scanner;

public class NarcissisticNumber {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入一个三位数:");
int n = scanner.nextInt();

// 验证是否为三位数
if (n < 100 || n > 999) {
System.out.println("no");
scanner.close();
return;
}

int original = n;
int sum = 0;

// 分离数位并计算立方和
while (n > 0) {
int digit = n % 10;
sum += digit * digit * digit; // 计算立方
n /= 10;
}

// 判断是否满足水仙花数条件
if (sum == original) {
System.out.println("yes");
} else {
System.out.println("no");
}

scanner.close();
}
}

2.2 判断火仙花数

题目:输入一个四位数,判断是否满足 ABCD = A⁴ + B⁴ + C⁴ + D⁴
输出要求:如果是火仙花数输出”yes”,否则输出”no”

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
import java.util.Scanner;

public class FourDigitNarcissistic {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入一个四位数:");
int n = scanner.nextInt();

// 验证是否为四位数
if (n < 1000 || n > 9999) {
System.out.println("no");
scanner.close();
return;
}

int original = n;
int sum = 0;

// 分离数位并计算四次方和
while (n > 0) {
int digit = n % 10;
int fourthPower = (int) Math.pow(digit, 4); // 使用Math.pow计算四次方
sum += fourthPower;
n /= 10;
}

// 判断是否满足火仙花数条件
if (sum == original) {
System.out.println("yes");
} else {
System.out.println("no");
}

scanner.close();
}
}

扩展,如果不知道有几位

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
import java.util.Scanner;

public class NarcissisticNumberUniversal {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();

if (n < 0) {
System.out.println("no");
} else {
int original = n;
int digitCount = 0;
int sum = 0;

// 先计算位数
int temp = n;
while (temp > 0) {
digitCount++;
temp /= 10;
}

// 计算各位数字的digitCount次方和
temp = n;
while (temp > 0) {
int digit = temp % 10;
// 使用Math.pow计算digit的digitCount次方
int power = (int) Math.pow(digit, digitCount);
sum += power;
temp /= 10;
}

System.out.println(sum == original ? "yes" : "no");
}
scanner.close();
}
}

3. 因数相关

3.1 输出所有因数

题目:输入一个数,输出该数的所有因数
样例:输入6,输出1 2 3 6
理解因数的概念:如果整数 a 除以整数 b(b≠0)的商正好是整数且没有余数,那么 b 就是 a 的因数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
// 创建扫描器对象,用于接收用户输入
Scanner scanner = new Scanner(System.in);

// 提示用户输入一个数
System.out.print("请输入一个数:");
int num = scanner.nextInt();

// 输出该数的所有因数
System.out.print(num + "的所有因数是:");
for (int i = 1; i <= num; i++) {
// 判断i是否是num的因数
if (num % i == 0) {
System.out.print(i + " ");
}
}
scanner.close();
}
}

3.2 判断完数(P66 4.7)

题目:输入一个数,判断是否是完数(所有真因子之和等于该数本身)
输出要求:如果是完数输出”yes”,否则输出”no”

理解完数概念:完数是指一个数的所有真因子(不包括自身)之和等于该数本身。例如 6 的真因子是 1、2、3,其和为 6,所以 6 是完数。
处理特殊情况:1 没有真因子,所以不是完数
查找真因子:从 1 到 n/2 遍历(因为一个数的真因子最大不超过其一半),找出所有能整除 n 的数
求和判断:将所有真因子求和,若和等于原数则为完数,否则不是

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
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();
scanner.close();

// 1不是完数
if (num <= 1) {
System.out.println("no");
return;
}

int sum = 0;
// 查找所有真因子(不包括自身)
for (int i = 1; i <= num / 2; i++) {
if (num % i == 0) {
sum += i;
}
}

// 判断真因子之和是否等于该数
if (sum == num) {
System.out.println("yes");
} else {
System.out.println("no");
}
}
}

3.3 判断质数(素数)

题目:输入一个数,判断是否是质数
输出要求:如果是质数输出”yes”,否则输出”no”

理解质数概念:质数是指大于 1 的自然数,除了 1 和它本身之外没有其他正因数。
特殊情况处理

  • 小于等于 1 的数不是质数
  • 2 是最小的质数,也是唯一的偶数质数

优化判断范围:对于大于 2 的数,只需判断到它的平方根即可(因为如果 n 有一个大于其平方根的因数,那么必定有一个小于其平方根的对应因数)
排除偶数:大于 2 的偶数一定不是质数,可以直接排除

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
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();
scanner.close();

// 处理小于等于1的情况
if (num <= 1) {
System.out.println("no");
return;
}

// 2是质数
if (num == 2) {
System.out.println("yes");
return;
}

// 偶数不是质数
if (num % 2 == 0) {
System.out.println("no");
return;
}

// 检查从3到平方根的所有奇数
for (int i = 3; i <= Math.sqrt(num); i += 2) {
if (num % i == 0) {
System.out.println("no");
return;
}
}

// 所有检查都通过,是质数
System.out.println("yes");
}
}

3.4 分解质因数

题目:输入一个数,分解质因数
样例:输入12,输出12=223

质因数概念:质因数是指能整除给定正整数的质数,分解质因数就是将一个数表示为若干个质数相乘的形式。
分解方法:从最小的质数 2 开始,不断尝试整除输入的数,直到不能整除为止,再用下一个可能的质数继续尝试,直到这个数被分解为 1。
处理过程

  • 初始化一个质数因子(从 2 开始)
  • 当该因子的平方小于等于当前数时,循环检查
  • 如果能整除,记录该因子并将原数除以该因子
  • 如果不能整除,将因子加 1(只需要检查到平方根即可优化效率)
  • 最后如果剩余的数大于 1,说明它本身也是一个质因数
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
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();
scanner.close();

System.out.print(num + "=");
int n = num;

// 处理2这个特殊的质数(唯一的偶数质数)
while (n % 2 == 0) {
System.out.print(2);
n /= 2;
if (n != 1) {
System.out.print("*");
}
}

// 处理奇数因子,从3开始
int i = 3;
while (i * i <= n) {
while (n % i == 0) {
System.out.print(i);
n /= i;
if (n != 1) {
System.out.print("*");
}
}
i += 2; // 只检查奇数
}

// 如果剩下的数大于1,说明它本身是一个质数
if (n > 1) {
System.out.print(n);
}
}
}

4. 阶乘相关

4.1 求阶乘

题目:输入n,求n的阶乘
样例:输入5,输出120

阶乘概念:n 的阶乘(记作 n!)是从 1 到 n 的所有正整数的乘积,即 n! = 1×2×3×…×n,特别规定 0! = 1。
实现方法:可以通过循环从 1 遍历到 n,将每次的数字累乘起来得到结果。
注意事项:阶乘的值增长非常快,对于较大的 n(如超过 20),int 类型可能会溢出,因此使用 long 类型存储结果更合适。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
scanner.close();

// 使用long类型存储结果,避免int类型溢出
long factorial = 1;

// 计算阶乘
for (int i = 1; i <= n; i++) {
factorial *= i;
}

System.out.println(factorial);
}
}

4.2 求阶乘和(P66 4.4)

题目:输入n,求1! + 2! + 3! + … + n!
样例:输入5,输出153

阶乘和概念:求 1! + 2! + 3! + … + n! 的总和,即从 1 的阶乘一直加到 n 的阶乘。
实现方法:可以在循环中同时计算每个数的阶乘和累加总和,避免重复计算(例如计算 3! 时可以基于 2! 的结果再乘以 3)。
注意事项:由于阶乘值增长很快,总和也会迅速变大,使用 long 类型存储结果更合适。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
scanner.close();

long sum = 0; // 存储阶乘和
long factorial = 1; // 存储当前数的阶乘

for (int i = 1; i <= n; i++) {
factorial *= i; // 计算i的阶乘(基于前一个数的阶乘)
sum += factorial; // 累加当前阶乘到总和
}

System.out.println(sum);
}
}