[Java] 实验13
2016-05-31 23:40
549 查看
1. 分段函数
1. 用 if - else if - else, 可以表达这三个分支。
2. 保留小数
之所以用 Math.round() 去保留小数,而不是 * 100d / 100, 是因为后者无法处理负数的情况。具体可以参考实验5. 求一元二次方程的根
在此给出保留任意位小数的方法 remainDigits.
大家应该理解下述原理,自行实现保留两位小数 或 保留任意位小数 的功能。
3. 对 System.out.println(double number) 的解释
用 println 输出一个 double 的时候,它总是会忽略这个数值的后导0.
- 如果 number 的值是一个整数(比如 5.0000),因为它的类型是 double, 那么会输出 5.0;
- 如果 number 的值是 5.1000, 在保留两位小数后,它会输出 5.1;
- 如果 number 的值是 5.1010, 在保留两位小数后,它会输出 5.1.
- 如果 number 的值是 5.1050, 在保留两位小数后,它会输出 5.11.
这是应该是语法决定的,还望大家不要纠结。
大家只需要关注如何正确地保留两位小数即可。
代码:
2. 输入 2 个正整数 m 和 n, 输出 m 和 n 之间所有能被 7 或 11 整除,但不能被两者同时整除的数。
3. 计算近似的 PI
4. 输出从元旦到该日经过的天数
1. 闰年的定义参考 实验 8. 40035 计算某月的天数
2. 这题可以通过定义一个含有 12 个月份的天数的数组 int[] days = { ... };
注意,需要根据是否是闰年,修改数组的第 1 个元素;
譬如,求 1月1号 到 3月8号 有多少天,那么只需要从 days[0] + days[1] + 8 - 1 即可。
5. 给学生成绩排降序
排序方法可以参考实验12. 60030 编写排序函数(方法)
在此我假设学生学号为 String 类型,学生成绩为 double 类型。我们要做的是:
1. 维护两个数组:学号数组 ids 和成绩数组 grades,该数组满足学生 ids[index] 对应的成绩即为 grades[index]. 亦即通过相同的下标,建立学号和成绩的一一对应关系。
2. 在给成绩降序排序的同时,维护这个一一对应关系:如果在成绩数组中交换了元素 grades[i] 和 grades[j]. 那么我们也在学号数组中,交换 ids[i] 和 ids[j].
假设题目输入满足下列格式:
6. 计算最大数的出现次数
7. 回文素数
在此没有引入 String 类,这样使得要解决这题,不需要依赖(记住)其他方法 (method), 只依赖更为基础的编程知识。
我们可以通过下述方法,判断一个数,比如说数字 32123 是否为回文:
- 通过 32123 / 10000, 取最左边的数字 3, 通过 32123 % 10 取最右边的数字 3. 比较这两个数字是否相同
- 拿掉最左边和最右边的数字 3,数字变成 212. 通过 212 / 100, 取最左边的数字 2, 通过 212 % 10 取最右边的数字 2. 比较这两个数字是否相同
- 拿掉最左边和最右边的数字 2,数字变成 1. 所以这是一个回文数。
9. 显示素数因子
10. 统计在字符串中每个数字出现的次数
1. int 数组中每个元素的默认值是 0, 原因可以参考 实验5. Q10
2. 代码:
13. 计算两个日期间的天数,并以二进制形式输出
在此我们把问题简化为:
- 计算给定 year1, yaer2 中间那些年份的日期 days1
- 计算 year1/month1/day1 到年终的那段日期 days2
- 计算 year2/month2/day2 距离该年元旦已经过的日期 days3
days1 + days2 + days3 即为所得。
注意到,上述方法可以处理所有情况。
14. 数字加密
a. 学习简单的数字加密有什么用?
学习数字加密,我们可以比较好的保护自己的信息安全:
- 对于每个网站,我们的密码可以由 公共前缀(prefix) + 特殊后缀(postfix) 组成
- 我们对后缀进行加密,得到新的字符串 prefix + encrypt(postfix), 将它作为我们的密码。
- 而在记录本中,我们只记录自己的 prefix 和 postfix.
由于加密算法由我们唯一拥有,所以即使这个记录本被别人拿走了,他们仍然无法猜出我们的密码;
不仅如此,我们的每个网站都有着唯一的密码 (你们的助教就是这么做的;)
b. 回到原题
代码如下:
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
一下题目为 10.77.30.33 网上的实验 13, 应该是不要求完成的。
70001
参考《Java语言程序设计--基础篇》:
- 8.1 引言
- 8.2 定义对象的类。简单描述了语法规则
- 8.3 举例:定义类和创建对象。以 Circle 为例。
代码填空:
70002 设计一个立方体类
基础和代码参考 70001.
同时注意到,我们在此不像 70001 那样,编写一个 CircleTest 放 main, 另一个 Circle 类放其他方法。事实上,我们只需要一个 Cube 就可以完成题目要求。(70001 也只需要一个 Circle 类,也是可以完成要求——只要把 public static void main 也放进 Circle 中即可)
代码填空:
70011 设计一个Circle的子类——圆柱体Cylinder
参考《Java语言程序设计--基础篇》,第 11 章 继承和多态:
- 11.1 引言
- 11.2 父类和子类。给出了父类与子类的图例,同时给出了相应的代码实现。
程序填空:
70012 编写重载方法,求二个数或三个数的最大值
1. 用 if - else if - else, 可以表达这三个分支。
2. 保留小数
之所以用 Math.round() 去保留小数,而不是 * 100d / 100, 是因为后者无法处理负数的情况。具体可以参考实验5. 求一元二次方程的根
在此给出保留任意位小数的方法 remainDigits.
大家应该理解下述原理,自行实现保留两位小数 或 保留任意位小数 的功能。
public class Test { public static void main(String[] args) { double num = 3.1415926535; for (int i = 0; i <= 10; ++ i) { System.out.println(remainDigits(num, i)); } } static double remainDigits(double num, int digitsToRemain) { // e.g. remainDigits(3.14159, 2) was called, then it will return // Math.round(3.14159 * 100d) / 100d, which equals 3.14 return Math.round(num * Math.pow(10, digitsToRemain)) / Math.pow(10, digitsToRemain); } }
3. 对 System.out.println(double number) 的解释
用 println 输出一个 double 的时候,它总是会忽略这个数值的后导0.
- 如果 number 的值是一个整数(比如 5.0000),因为它的类型是 double, 那么会输出 5.0;
- 如果 number 的值是 5.1000, 在保留两位小数后,它会输出 5.1;
- 如果 number 的值是 5.1010, 在保留两位小数后,它会输出 5.1.
- 如果 number 的值是 5.1050, 在保留两位小数后,它会输出 5.11.
这是应该是语法决定的,还望大家不要纠结。
大家只需要关注如何正确地保留两位小数即可。
代码:
public class Test { public static void main(String[] args) { System.out.println(remainDigits(5.0000, 2)); // Output 5.0 System.out.println(remainDigits(5.1000, 2)); // Output 5.1 System.out.println(remainDigits(5.1010, 2)); // Output 5.1 System.out.println(remainDigits(5.1050, 2)); // Output 5.11 } static double remainDigits(double num, int digitsToRemain) { // e.g. remainDigits(3.14159, 2) was called, then it will return // Math.round(3.14159 * 100d) / 100d, which equals 3.14 return Math.round(num * Math.pow(10, digitsToRemain)) / Math.pow(10, digitsToRemain); } }
2. 输入 2 个正整数 m 和 n, 输出 m 和 n 之间所有能被 7 或 11 整除,但不能被两者同时整除的数。
if ((num % 7 == 0 || num % 11 == 0) && num % 77 != 0) { // Print the result here }
3. 计算近似的 PI
4. 输出从元旦到该日经过的天数
1. 闰年的定义参考 实验 8. 40035 计算某月的天数
2. 这题可以通过定义一个含有 12 个月份的天数的数组 int[] days = { ... };
注意,需要根据是否是闰年,修改数组的第 1 个元素;
譬如,求 1月1号 到 3月8号 有多少天,那么只需要从 days[0] + days[1] + 8 - 1 即可。
5. 给学生成绩排降序
排序方法可以参考实验12. 60030 编写排序函数(方法)
在此我假设学生学号为 String 类型,学生成绩为 double 类型。我们要做的是:
1. 维护两个数组:学号数组 ids 和成绩数组 grades,该数组满足学生 ids[index] 对应的成绩即为 grades[index]. 亦即通过相同的下标,建立学号和成绩的一一对应关系。
2. 在给成绩降序排序的同时,维护这个一一对应关系:如果在成绩数组中交换了元素 grades[i] 和 grades[j]. 那么我们也在学号数组中,交换 ids[i] 和 ids[j].
假设题目输入满足下列格式:
3 3150100001 86.5 3150100002 88.5 3150100003 87.5我们的程序可以写成:
// Assume the input has the format like this: // student_number // student1_id grade // student2_id grade // ... import java.util.Scanner; public class GradeSort { public static void main(String[] args) { Scanner in = new Scanner(System.in); // Input int studentNumber = in.nextInt(); // Use "String" instead of "int" to represent the student ID, // in case it might larger than the maximal value "int" can hold String[] ids = new String[studentNumber]; // Use "double" to represent the student grade // in case it might be a floating-point instead of an integer. double[] grades = new double[studentNumber]; for (int i = 0; i < studentNumber; ++ i) { ids[i] = in.next(); // Input String grades[i] = in.nextDouble(); // Input double } // Bubble sort bubbleSort(ids, grades); // Output for (String id: ids) System.out.println(id); } static void bubbleSort(String[] ids, double[] grades) { for (int i = 1; i < grades.length; ++ i) { for (int j = i; j >= 1; -- j) { if (grades[j] > grades[j - 1]) { swap(grades, j, j -1); swap(ids, j, j - 1); } } } } // Note that we could use the "generic" property to implement ONLY ONE // swap method here, while this property is beyond your course requirement. static void swap(String[] ids, int i, int j) { String temp = ids[i]; ids[i] = ids[j]; ids[j] = temp; } static void swap(double[] grades, int i, int j) { double temp = grades[i]; grades[i] = grades[j]; grades[j] = temp; } }
6. 计算最大数的出现次数
for (int x = in.nextInt(); x != 0; x = in.nextInt()) { // Do your statistics here. }
7. 回文素数
在此没有引入 String 类,这样使得要解决这题,不需要依赖(记住)其他方法 (method), 只依赖更为基础的编程知识。
我们可以通过下述方法,判断一个数,比如说数字 32123 是否为回文:
- 通过 32123 / 10000, 取最左边的数字 3, 通过 32123 % 10 取最右边的数字 3. 比较这两个数字是否相同
- 拿掉最左边和最右边的数字 3,数字变成 212. 通过 212 / 100, 取最左边的数字 2, 通过 212 % 10 取最右边的数字 2. 比较这两个数字是否相同
- 拿掉最左边和最右边的数字 2,数字变成 1. 所以这是一个回文数。
public class PalindromicPrime { public static void main(String[] args) { for (int i = 2, count = 0; count < 50; ++ i) if (prime(i) && palindrome(i)) { System.out.print(i + " " + (++ count % 10 == 0? "\n": "")); } } // Determine whether a number is prime or not static boolean prime(int num) { for (int i = 2; i <= Math.sqrt(num); ++ i) if (num % i == 0) return false; return true; } // Determine whether a number is palindromic or not static boolean palindrome(int num) { int digitNum = 1; for (int temp = num / 10; temp != 0; temp /= 10) ++ digitNum; // Thus num has # of digitNum digits // e.g. Number 0 has 1 digit, digitNum = 1 // Number 52 has 2 digits, digitNum = 2 // Number 123 has 3 digits, digitNum = 3 while (digitNum > 1) { int leftmostDigit = (int) (num / Math.pow(10, digitNum - 1)); int rightmostDigit = num % 10; if (leftmostDigit != rightmostDigit) return false; num = (num % (int)Math.pow(10, digitNum - 1)) / 10; digitNum = digitNum - 2; } return true; } }
9. 显示素数因子
public class PrimeFactor { public static void main(String[] args) { Scanner in = new Scanner(System.in); int num = in.nextInt(); for (int i = num; i != 1; -- i) if (prime(i)) for (; num % i == 0; num /= i) System.out.print(i + " "); in.close(); } // Determine whether a number is prime or not static boolean prime(int num) { for (int i = 2; i <= Math.sqrt(num); ++ i) if (num % i == 0) return false; return true; } }
10. 统计在字符串中每个数字出现的次数
1. int 数组中每个元素的默认值是 0, 原因可以参考 实验5. Q10
2. 代码:
public static int[] count(String s) { int[] res = new int[10]; for (int i = 0; i < s.length(); ++ i) if (s.charAt(i) >= '0' && s.charAt(i) <= '9') ++ res[s.charAt(i) - '0']; return res; }
13. 计算两个日期间的天数,并以二进制形式输出
在此我们把问题简化为:
- 计算给定 year1, yaer2 中间那些年份的日期 days1
- 计算 year1/month1/day1 到年终的那段日期 days2
- 计算 year2/month2/day2 距离该年元旦已经过的日期 days3
days1 + days2 + days3 即为所得。
注意到,上述方法可以处理所有情况。
import java.util.Scanner; public class Days { public static void main(String[] args) { // Input Scanner in = new Scanner(System.in); int year1 = in.nextInt(); int month1 = in.nextInt(); int day1 = in.nextInt(); int year2 = in.nextInt(); int month2 = in.nextInt(); int day2 = in.nextInt(); in.close(); // Begin calculation int sum = 0; if (year1 != year2) { // Days between [(year1+1)/01/01, (year2-1)/12/lastDay] for (int i = year1 + 1; i < year2; ++i) sum += leapYear(i) ? 366 : 365; // Days between [year1/month1/day1, year1/12/lastDay] sum += (leapYear(year1) ? 366 : 365) - (days(year1, month1, day1) - 1); // Days between [year2/01/01, year2/month2/day2] sum += days(year2, month2, day2); } else { sum = days(year2, month2, day2) - days(year1, month1, day1) + 1; } // Output the result decToBin(sum); } private static boolean leapYear(int year) { return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0); } // Days between [year/01/01, year/month/day] // i.e. days(2016, 03, 01) = 31 + 29 + 1 = 61 private static int days(int year, int month, int day) { int sum = 0; int[] daysInMonth = { 31, leapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; for (int i = 0; i < month - 1; ++i) sum += daysInMonth[i]; return sum + day; } // Note that we're going to solve this problem recursively (递归地解决问题) // Decimal to binary private static void decToBin(int n) { if (n != 0) { // Print the higher bit first decToBin(n >> 1); // Then print the lower bit System.out.print(n % 2); } } }
14. 数字加密
a. 学习简单的数字加密有什么用?
学习数字加密,我们可以比较好的保护自己的信息安全:
- 对于每个网站,我们的密码可以由 公共前缀(prefix) + 特殊后缀(postfix) 组成
- 我们对后缀进行加密,得到新的字符串 prefix + encrypt(postfix), 将它作为我们的密码。
- 而在记录本中,我们只记录自己的 prefix 和 postfix.
由于加密算法由我们唯一拥有,所以即使这个记录本被别人拿走了,他们仍然无法猜出我们的密码;
不仅如此,我们的每个网站都有着唯一的密码 (你们的助教就是这么做的;)
b. 回到原题
代码如下:
import java.util.Scanner; public class Encrption { public static void main(String[] args) { Scanner in = new Scanner(System.in); String num1 = in.next(); String num2 = in.next(); String result = ""; char[] table = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'J', 'Q', 'K' }; int i = num1.length() - 1, j = num2.length() - 1; for (boolean isOdd = true; i >= 0 && j >= 0; -- i, -- j, isOdd = !isOdd) { if (isOdd) { int num = (num1.charAt(i) - '0' + num2.charAt(j) - '0') % 13; result = table[num] + result; } else { int num = num2.charAt(j) - num1.charAt(i); num = num > 0? num: num + 10; result = table[num] + result; } } for (; j >= 0; -- j) result = table[num2.charAt(j) - '0'] + result; System.out.println(result); in.close(); } }
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
一下题目为 10.77.30.33 网上的实验 13, 应该是不要求完成的。
70001
参考《Java语言程序设计--基础篇》:
- 8.1 引言
- 8.2 定义对象的类。简单描述了语法规则
- 8.3 举例:定义类和创建对象。以 Circle 为例。
代码填空:
import java.util.*; public class CircleTest { public static void main(String args[]) { Scanner in = new Scanner(System.in); int repeat= in.nextInt(); while (repeat-- != 0) { float radius = in.nextFloat(); Circle cir = new Circle(); cir.setRadius(radius); System.out.println(Math.round(cir.area())); System.out.println(Math.round(cir.perimeter())); } in.close(); } } class Circle { void setRadius(float radius) { radius_ = radius; } // According to the problem specification, the type of the return value // should be double double area() { ? } // According to the problem specification, the type of the return value // should be double double perimeter() { ? } float radius_; }
70002 设计一个立方体类
基础和代码参考 70001.
同时注意到,我们在此不像 70001 那样,编写一个 CircleTest 放 main, 另一个 Circle 类放其他方法。事实上,我们只需要一个 Cube 就可以完成题目要求。(70001 也只需要一个 Circle 类,也是可以完成要求——只要把 public static void main 也放进 Circle 中即可)
代码填空:
import java.util.Scanner; public class Cube { public static void main(String[] args) { Scanner in = new Scanner(System.in); double length = in.nextDouble(); System.out.println("Length=" + cube1.getLength()); System.out.println("Surface area=" + cube1.calcArea()); System.out.println("Volume=" + cube1.calcV()); } ? setLength(?) { ? } ? getLength(?) { ? } // Define your calcArea here ? // Define your calcVolume here ? double length_; }
70011 设计一个Circle的子类——圆柱体Cylinder
参考《Java语言程序设计--基础篇》,第 11 章 继承和多态:
- 11.1 引言
- 11.2 父类和子类。给出了父类与子类的图例,同时给出了相应的代码实现。
程序填空:
import java.util.Scanner; public class CylinderTest { public static void main(String[] args) { Scanner in = new Scanner(System.in); double x = in.nextDouble(); double y = in.nextDouble(); double r = in.nextDouble(); double h = in.nextDouble(); // Note that we just ignore the x, y, whose reason has been explained // in line 21. Cylinder cy = new Cylinder(r, h); System.out.println("r=" + cy.getRadius()); System.out.println("h=" + cy.getHeight()); System.out.println("V=" + Math.round(cy.calcVolume() * 100) / 100.); System.out.println("S=" + Math.round(cy.calcArea() * 100) / 100.); } } class Circle { // The reason we abandon x, y here is we are NOT gonna use them actually public Circle(double r) { // Thus for a circle, the only information needed to remain is its radius this.radius_ = r; } // Calculate the perimeter for this circle public double perimeter() { return 2 * Math.PI * radius_; } // Calculate the area for this circle public double area() { return Math.PI * radius_ * radius_; } public double getRadius() { return radius_; } private double radius_; } class Cylinder extends Circle { Cylinder(double radius, double height) { // Call its parent's constructor, Circle(radius), by calling super(radius) super(radius); // Initialize its own filed height_ = height; } // Define your calcArea here ? // Define your calcVolumn here ? // Define your getHeight here ? private double height_; }
70012 编写重载方法,求二个数或三个数的最大值
import java.util.Scanner; public class CompareTest { public static void main(String[] args) { Scanner in = new Scanner(System.in); int repeat = in.nextInt(); while (repeat-- != 0) { int a = in.nextInt(); int b = in.nextInt(); int c = in.nextInt(); System.out.println("max(a,b)=" + Compare.max(a, b)); System.out.println("max(a,b,c)=" + Compare.max(a, b, c)); } in.close(); } } class Compare { static int max(int a, int b) { ? } static int max(int a, int b, int c) { ? } }
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树