1. 程式人生 > >PAT-乙-1034 1034 有理數四則運算 (20 分)

PAT-乙-1034 1034 有理數四則運算 (20 分)

在這裡插入圖片描述

程式碼

#include <iostream>
#include <math.h>
#include <stdio.h>
using namespace std;

struct fenshu {
	long long int fenzi;
	long long int fenmu;
};

//輾轉相除求最大公約數 
long long int maxFactor(long long int a, long long int b) {
	if(a==0 || b==0){
		return 1;
	}
	if(a<b){
		long long int tmp = a;
		a = b;
		b = tmp;
	}
	while(a%b){
		long long int reminder = a%b;
		a = b;
		b = reminder;
	}
	return b;
}

//分數簡化 
void simplify(fenshu &f) {
	long long int maxF = maxFactor(abs(f.fenzi), abs(f.fenmu));
	if(maxF>0) {
		f.fenzi /= maxF;
		f.fenmu /= maxF;
	}
	if(f.fenzi*f.fenmu<0) {
		f.fenzi = -1 * abs(f.fenzi);
		f.fenmu = abs(f.fenmu);
	} else {
		f.fenzi = abs(f.fenzi);
		f.fenmu = abs(f.fenmu);
	}
}

//四則運算 
fenshu ope(fenshu f1, fenshu f2, char ch) {
	fenshu re;
	switch(ch) {
		case '+':
			re.fenmu = f1.fenmu * f2.fenmu;
			re.fenzi = f1.fenzi * (re.fenmu/f1.fenmu) + f2.fenzi * (re.fenmu/f2.fenmu);
			break;
		case '-':
			re.fenmu = f1.fenmu * f2.fenmu;
			re.fenzi = f1.fenzi * (re.fenmu/f1.fenmu) - f2.fenzi * (re.fenmu/f2.fenmu);
			break;
		case '*':
			re.fenmu = f1.fenmu * f2.fenmu;
			re.fenzi = f1.fenzi * f2.fenzi;
			break;
		case '/':
			re.fenmu = f1.fenmu * f2.fenzi;
			re.fenzi = f1.fenzi * f2.fenmu;
			break;
	}
	simplify(re);
	return re;
}

//輸出一個分數 
void outputNum(fenshu f) {
	if(f.fenmu==0) {
		printf("Inf");
		return;
	}
	long long int tmpFenzi = f.fenzi;
	long long int zheng = 0;
	long long int xiaoshu = 0;
	if(abs(f.fenzi)/f.fenmu>0) {
		zheng = abs(f.fenzi)/f.fenmu;
	}
	if(abs(f.fenzi)%f.fenmu>0) {
		f.fenzi = abs(f.fenzi)%f.fenmu;
		xiaoshu = 1;
	}

	if(tmpFenzi!=0) {
		if(tmpFenzi<0){
			printf("(-");
		}
		if(zheng) {
			printf("%lld", zheng);
		}
		if(xiaoshu) {
			if(zheng) {
				printf(" %lld/%lld", f.fenzi, f.fenmu);
			} else {
				printf("%lld/%lld", f.fenzi, f.fenmu);
			}
		}
		if(tmpFenzi<0){
			printf(")");
		}
	} else {
		printf("0");
	}
}

//按題目要求輸出結果 
void output(fenshu f1, fenshu f2, fenshu ans, char ch) {
	outputNum(f1);
	printf(" %c ", ch);
	outputNum(f2);
	printf(" = ");
	outputNum(ans);
	printf("\n");
}

int main() {

	fenshu f1, f2;
	scanf("%lld/%lld %lld/%lld", &f1.fenzi, &f1.fenmu, &f2.fenzi, &f2.fenmu);
	simplify(f1);
	simplify(f2);
	string op = "+-*/";
	for(int i=0; i<op.length(); i++) {
		fenshu ans = ope(f1, f2, op.at(i));
		output(f1, f2, ans, op.at(i));
	}

	return 0;
}

註解

1、c++需要用long long int,否則會有兩個案例是答案錯誤。推測是中間計算過程中有越界
2、求最大公約數要用輾轉相除法,否則暴力求解會有一個案例執行超時!此外注意如果輸入有0,求最大公約數直接返回1即可。
3、統一把負號放在分子上。整數和小數的輸出形式單獨考慮。

結果

在這裡插入圖片描述