[Java] 实验7参考代码

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();
  }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值