此代码包含了分数的操作,包含以下操作:
约分;
求最大公因数和最小公倍数;
分数各项运算;
假分数转换成带分数。
#include<iostream>
#include<string>
#include<sstream>
#include<cmath>
#include<bits/stdc++.h>
using namespace std;
int gcd(int a,int b) {
return !b?a:gcd(b,a%b);
}
int lcm(int a,int b) {
return a*b/gcd(a,b);
}
pair<int, int> simplify(int numerator, int denominator) {
if(denominator == 0) throw invalid_argument("分母不能为零");
if(numerator == 0) return {0, 1};
int g = gcd(abs(numerator), abs(denominator));
return {numerator / g, denominator / g};
}
void printFractionLine(int num) {
int digits = 0;
if(num == 0) digits = 1;
else while(num) {
digits++;
num /= 10;
}
cout << string(digits, '-') << endl;
}
void printFraction(int numerator, int denominator) {
cout << numerator << endl;
printFractionLine(max(abs(numerator), abs(denominator)));
cout << denominator << endl;
}
pair<int, int> addFractions(int n1, int d1, int n2, int d2) {
if(d1 == 0 || d2 == 0) throw invalid_argument("分母不能为零");
int lcm_val = d1 * d2 / gcd(d1, d2);
int result_n = n1 * (lcm_val / d1) + n2 * (lcm_val / d2);
return simplify(result_n, lcm_val);
}
pair<int, int> subtractFractions(int n1, int d1, int n2, int d2) {
return addFractions(n1, d1, -n2, d2);
}
pair<int, int> multiplyFractions(int n1, int d1, int n2, int d2) {
if(d1 == 0 || d2 == 0) throw invalid_argument("分母不能为零");
return simplify(n1 * n2, d1 * d2);
}
pair<int, int> divideFractions(int n1, int d1, int n2, int d2) {
if(d1 == 0 || d2 == 0 || n2 == 0) throw invalid_argument("分母或除数不能为零");
return simplify(n1 * d2, d1 * n2);
}
void improperToMixed(int numerator, int denominator) {
if(denominator == 0) throw invalid_argument("分母不能为零");
int whole = numerator / denominator;
int remainder = numerator % denominator;
if(remainder == 0) {
cout << "结果: " << whole << endl;
return;
}
auto simplified = simplify(remainder, denominator);
cout << "结果: \n" << whole << " 又\n";
printFraction(simplified.first, simplified.second);
}
void showMenu() {
cout << "******************\n";
cout << "****分数计算器****\n";
cout << "******************\n";
cout << "0. 退出\n";
cout << "1. 约分\n";
cout << "2. 求最大公因数和最小公倍数\n";
cout << "3. 分数加法\n";
cout << "4. 分数减法\n";
cout << "5. 分数乘法\n";
cout << "6. 分数除法\n";
cout << "7. 假分数转带分数\n";
cout << "请输入操作编号: ";
}
int getValidInt(const string& prompt) {
int value;
while(true) {
cout << prompt;
if(cin >> value) {
cin.ignore(numeric_limits<streamsize>::max(), '\n');
return value;
} else {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "输入无效,请输入整数。" << endl;
}
}
}
int main() {
int choice;
while(true) {
system("cls");
showMenu();
choice = getValidInt("");
if(choice == 0) break;
try {
switch(choice) {
case 1: {
int numerator = getValidInt("输入分子: ");
int denominator = getValidInt("输入分母: ");
auto result = simplify(numerator, denominator);
cout << "约分结果:" << endl;
printFraction(result.first, result.second);
break;
}
case 2: {
int sub_choice = getValidInt("1. 最大公因数\n2. 最小公倍数\n请选择: ");
int a = getValidInt("输入第一个数: ");
int b = getValidInt("输入第二个数: ");
if(sub_choice == 1) cout << "gcd(" << a << ", " << b << ") = " << gcd(a, b) << endl;
else if(sub_choice == 2) cout << "lcm(" << a << ", " << b << ") = " << lcm(a, b) << endl;
else cout << "无效选择" << endl;
break;
}
case 3: {
int n1 = getValidInt("第一个分数 - 分子: ");
int d1 = getValidInt("第一个分数 - 分母: ");
int n2 = getValidInt("第二个分数 - 分子: ");
int d2 = getValidInt("第二个分数 - 分母: ");
cout << "第一个分数:" << endl;
printFraction(n1, d1);
cout << "第二个分数:" << endl;
printFraction(n2, d2);
auto result = addFractions(n1, d1, n2, d2);
cout << "加法结果:" << endl;
printFraction(result.first, result.second);
break;
}
case 4: {
int n1 = getValidInt("第一个分数 - 分子: ");
int d1 = getValidInt("第一个分数 - 分母: ");
int n2 = getValidInt("第二个分数 - 分子: ");
int d2 = getValidInt("第二个分数 - 分母: ");
cout << "第一个分数:" << endl;
printFraction(n1, d1);
cout << "第二个分数:" << endl;
printFraction(n2, d2);
auto result = subtractFractions(n1, d1, n2, d2);
cout << "减法结果:" << endl;
printFraction(result.first, result.second);
break;
}
case 5: {
int n1 = getValidInt("第一个分数 - 分子: ");
int d1 = getValidInt("第一个分数 - 分母: ");
int n2 = getValidInt("第二个分数 - 分子: ");
int d2 = getValidInt("第二个分数 - 分母: ");
cout << "第一个分数:" << endl;
printFraction(n1, d1);
cout << "第二个分数:" << endl;
printFraction(n2, d2);
auto result = multiplyFractions(n1, d1, n2, d2);
cout << "乘法结果:" << endl;
printFraction(result.first, result.second);
break;
}
case 6: {
int n1 = getValidInt("第一个分数 - 分子: ");
int d1 = getValidInt("第一个分数 - 分母: ");
int n2 = getValidInt("第二个分数 - 分子: ");
int d2 = getValidInt("第二个分数 - 分母: ");
cout << "第一个分数:" << endl;
printFraction(n1, d1);
cout << "第二个分数:" << endl;
printFraction(n2, d2);
auto result = divideFractions(n1, d1, n2, d2);
cout << "除法结果:" << endl;
printFraction(result.first, result.second);
break;
}
case 7: {
int numerator = getValidInt("输入分子: ");
int denominator = getValidInt("输入分母: ");
improperToMixed(numerator, denominator);
break;
}
default:
cout << "无效操作编号" << endl;
}
} catch(const exception& e) {
cout << "错误: " << e.what() << endl;
}
cout << "\n按任意键继续...";
cin.ignore();
cin.get();
}
cout << "\n感谢使用分数计算器!\n\n";
return 0;
}