1. default package问题可参考实验6
2. for, if, while等,后面包含多条语句时,需要用花括号括起来
3. 为什么需要close scanner, 可参考实验6 (已简要更新原因)
求2/1+3/2+5/3+8/5+...
在第二行输出结果错误(输出10.3917)的同学,可以参考实验六“求1+1/2+1/3+……+1/n”第3点。
判断素数
判断一个1的数(n)是否是素数有很多种方法:
1. 遍历[2, n-1]区间,看区间中的每个数i是否都不可以整除n: 如果都不可以整除n, 那么n是素数。
2. 事实上,不需要遍历整个[2, n-1]区间,只需要遍历[2, Math.sqrt(n)]这个区间就可以了。这样带来的好处是,当n的值比较大,比如说n = 10^6时,不需要在进行大概一百万次的判断,只需要一千次就可以了——极大程度上提升了运算速度。
代码:
import java.util.Scanner;
public class IsPrime {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int repeat = in.nextInt();
while (repeat-- != 0)
System.out.println(isPrime(in.nextInt())? "YES": "NO");
in.close();
}
private static boolean isPrime(int n) {
boolean flag = n == 1? false: true;
for (int i = 2; i <= Math.sqrt(n) && flag; ++ i)
flag = n % i != 0;
return flag;
}
}
求最小公倍数和最大公约数
最大公约数(gcd)的求法可以参考维基百科——辗转相除法。举个例子,对于m = 8, n = 6
1) 8 % 6 = 2
2) 6 % 2 = 0, 最大公约数是2.
最小公倍数(lcm)的求法,举个特例,对于m = 8, n = 6, 我们可以:
1) 8和6的最大公约数为2.
2) 然后设法求出8和6的最小公倍数(24)
大家可以思考:已知m, n, gcd, 如何求出lcm。
代码:
import java.util.Scanner;
public class LcmAndGcd {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int repeat = in.nextInt();
while (repeat-- != 0) {
int m = in.nextInt();
int n = in.nextInt();
if (m <= 0 || n <= 0) {
System.out.println("m <= 0 or n <= 0");
} else {
int bigger = Math.max(m, n);
int smaller = Math.min(m, n);
int gcd = gcd(bigger, smaller);
int lcm = bigger * smaller / gcd;
System.out.println("the least common multiple:"+lcm+", the greatest common divisor:"+gcd);
}
}
in.close();
}
private static int gcd(int dividend, int divisor) {
if (dividend % divisor == 0) {
return divisor;
} else {
return gcd(divisor, dividend % divisor);
}
}
}
求各位数字的立方和等于它本身的数
1. 考察的是[m, n]这个闭区间 —— 这是题目不够严谨,没有说明
2. 本地测试通过,提交后发现答案错误的同学,可以试着用程序验证一下,当m=whatever, n=1000时,输出是否满足题意。
统计单词
解法一:题目提供的解法
1. 对于String对象(比如说line), 我们可以通过line.length()获得这个字符串的长度
2. 通过循环:
// 数组的下标是从0开始的
// 对于长度为len的数组array,只支持array[0], array[1], ..., array[len - 1]的下标访问
for (int i = 0; i < line.length(); ++ i) {
line.charAt(i); // 在循环的第i次迭代中,取出字符串中的第i个字符
}
解法二:
有兴趣的同学可以去http://docs.oracle.com/javase/8/docs/api, 搜索String类的split方法:
- line.split(regex)的作用是,以regex为规则去匹配line中的字符串,找到匹配的子串(substr)后会将这个子串作为分隔符,然后将字符串line切分。
- 返回切分后的字符串数组String[]
举些例子:
// e.g. 1
String line = "a b"; // a, b, c中间有一个空格
String[] res = line.split(" "); // 那么res = ["a", "b"]
// e.g. 2
String line = "a b"; // a, b, c中间有两个空格
String[] res = line.split(" "); // 那么res = ["a", "", "b"]
// 1. line在扫描的过程中碰到“第一个空格”,把空格之前的a作为返回数组中的一个值
// 2. 因为line的字符ab中间有两个空格,line的“第二个空格”和split的参数regex匹配,所以在这个两个空格间的值也会返回。这个值对应了返回数组的第二个参数,那个空值
// 3. line扫描到结尾,把最后一个空格(也就是第二个空格)和结尾之间的字符串"b"也返回。
// 所以返回结果是["a", "", "b"]
输出一个整数的各位数字
举个例子,对数字n = 12345, 我们有
- 12345 / 10000 = 1, 12345 % 10000 = 2345
- 2345 / 1000 = 2, 2345 % 1000 = 345
- ...
简单计算器
1. 输入解析。考虑输入“2 + 10 =”, 执行下述代码:
op1 = in.nextInt(); // 此时,op1 = 2
operator = (in.next()).charAt(0); // 此时,operator = '+'
op1 = in.nextInt(); // 此时,op1 = 10
operator = (in.next()).charAt(0); // 此时,operator = '='
2. 程序如何停止(如何停止输入)
请类比 40008. 求奇数和
3. 看清题意:四种运算优先级相同,从左往右运算。
4. 解题思路(这是我的思路,和题目给的程序不同)
1) 可以将res赋值为第一个输入的数字,res = in.nextInt()
2) 读取下一个操作符operator, 判断它是否为'='
- 若是,输出结果
- 反之,更新res, 重复2)
代码:
import java.util.Scanner;
public class Arithmetic {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int repeat = in.nextInt();
while (repeat-- != 0) {
int res = in.nextInt();
for (int operator = in.next().charAt(0); operator != '='; operator = in.next().charAt(0)) {
int op = in.nextInt();
switch (operator) {
case '+':
res += op;
break;
case '-':
res -= op;
break;
case '*':
res *= op;
break;
case '/':
res /= op;
break;
}
}
System.out.println(res);
}
in.close();
}
}