PAT乙級——1034(模擬四則運算)
阿新 • • 發佈:2019-01-08
題目:有理數四則運算 (20 分)
本題要求編寫程式,計算 2 個有理數的和、差、積、商。
輸入格式:
輸入在一行中按照 a1/b1 a2/b2
的格式給出兩個分數形式的有理數,其中分子和分母全是整型範圍內的整數,負號只可能出現在分子前,分母不為 0。
輸出格式:
分別在 4 行中按照 有理數1 運算子 有理數2 = 結果
的格式順序輸出 2 個有理數的和、差、積、商。注意輸出的每個有理數必須是該有理數的最簡形式k a/b
,其中 k
是整數部分,a/b
是最簡分數部分;若為負數,則須加括號;若除法分母為 0,則輸出 Inf
。題目保證正確的輸出中沒有超過整型範圍的整數。
輸入樣例 1: 2/3 -4/2 輸出樣例 1: 2/3 + (-2) = (-1 1/3) 2/3 - (-2) = 2 2/3 2/3 * (-2) = (-1 1/3) 2/3 / (-2) = (-1/3)
輸入樣例 2:
5/3 0/6
輸出樣例 2:
1 2/3 + 0 = 1 2/3
1 2/3 - 0 = 1 2/3
1 2/3 * 0 = 0
1 2/3 / 0 = Inf
題目分析
首先這個題目是模擬四則運算,有很多的小細節需要考慮,首先是給出的分數需要顯示正負,正負顯示不同,顯示整數和分數部分。
這個題目需要對分數的四則運算很清楚,同時,由於是分數的操作,則除法的運算是本題的核心。做了好久,想不出完美的解決辦法,借鑑了網上的程式碼,並給出了完整的註釋。
import java.util.Scanner;
public class Y1034 {
public static void main(String[ ] args) {
Scanner in = new Scanner(System.in);
String[] input = in.nextLine().split("[\\s/]");
in.close();
//分離出資料
long a1 = Integer.parseInt(input[0]);
long b1 = Integer.parseInt(input[1]);
long a2 = Integer.parseInt(input[2]);
long b2 = Integer.parseInt(input[3]);
//分母不為零,題目說了不能為零,在我看來可以不用寫這個判斷,可以刪去此處if語句
if (b1 != 0 && b2 != 0) {
add(a1, b1, a2, b2);
minus(a1, b1, a2, b2);
mutilply(a1, b1, a2, b2);
divide(a1, b1, a2, b2);
}
}
//判斷分子分母計算後的大小和正負,也可以當做是除法操作
public static void tackle(long a, long b) {
if (a == 0) {
//若分子為零,直接輸出0
System.out.print(0);
return;
}
//若分子小於零,則數值小於零,列印左括號和-號
boolean isMinus = a > 0 ? false : true;
if (isMinus) {
System.out.print("(-");
a = -a;//改值
}
long gcd = getGcd(a, b);//最大公約數
a = a / gcd;//約分操作
b = b / gcd;
if (a % b == 0) {
System.out.print(a / b);//無餘數,輸出整數
} else if (Math.abs(a) > b) {//a的絕對值大,則一定存在整數部
System.out.print(a / b + " " + a % b + "/" + b);//原始碼是(a % b) % b,對b取餘一定小於b,多做一次取餘操作還是原數,刪去
} /*//這一步與第一個重了,可以省去
else if (a == b) {
System.out.print(1);
}*/ else {
System.out.print(a + "/" + b);
}
if (isMinus) {//若列印了左括號,輸出右括號
System.out.print(")");
}
}
//除法
public static void divide(long a1, long b1, long a2, long b2) {
tackle(a1, b1);//計算第一個數並輸出
System.out.print(" / ");
tackle(a2, b2);//計算第二個數並輸出
System.out.print(" = ");
if (a2 == 0) {
System.out.print("Inf");
} else if (a2 < 0) {
//a/b 除 c/d = ad/bc
tackle(-1 * a1 * b2, -1 * a2 * b1);
} else {
tackle(a1 * b2, a2 * b1);
}
}
//乘法
public static void mutilply(long a1, long b1, long a2, long b2) {
tackle(a1, b1);
System.out.print(" * ");
tackle(a2, b2);
System.out.print(" = ");
//a/b 乘 c/d = ac/bd
tackle(a1 * a2, b1 * b2);
System.out.println();
}
//減法
public static void minus(long a1, long b1, long a2, long b2) {
tackle(a1, b1);
System.out.print(" - ");
tackle(a2, b2);
System.out.print(" = ");
//減法,a/b 減 c/d 通分做計算,分子為ad-bc,分母為bd
tackle(a1 * b2 - a2 * b1, b1 * b2);
System.out.println();
}
//加法
public static void add(long a1, long b1, long a2, long b2) {
tackle(a1, b1);
System.out.print(" + ");
tackle(a2, b2);
System.out.print(" = ");
//加法,a/b 加 c/d 通分做計算,分子為ad+bc,分母為bd
tackle(a1 * b2 + a2 * b1, b1 * b2);
System.out.println();
}
//迭代法(遞推法):歐幾里得演算法:計算分子分母的最大公約數
public static long getGcd(long a, long b) {
while (a % b != 0) {
long temp = a % b;
a = b;
b = temp;
}
return b;
}
}