您的位置:首页 > 编程语言 > Java开发

[Java] 实验13

2016-05-31 23:40 549 查看
1. 分段函数

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