1. 程式人生 > >PAT乙級——1034(模擬四則運算)

PAT乙級——1034(模擬四則運算)

題目:有理數四則運算 (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; } }