1. /*
    2. * 程序思路说明
    3. * 1/3本身是两个数据进行运算的语句,如果要把它变成一个整体,
    4. * 就需要定义Integer类和Fraction类,这样Fraction类定义的变量可以是 1/3这种形式。
    5. * 1/3 + 1/2 = 5/6这种运算若要成立就需要对四则运算符进行重载(重新定义+ - * /四种运算方法)
    6. * 重载运算符的思路:
    7. * 输入运算符要想实现1/3和2/3进行运算的形式,输入运算符需要重载
    8. * 如果分数相加,就要有通分的过程,重载加法运算符的时候就要把通分的算法写进去
    9. * 减法也需要通分,所以和加法思路差不多
    10. * 乘法的思路是分子乘分子,分母乘分母,然后再约分
    11. * 除法思路是将被除数取倒数,然后再用乘法的思路
    12. * 至于说输出也需要重载,真分数可以是最简分数的形式输出
    13. * 对于假分数来说,分子比分母大,可以用带分数的形式输出
    14. * 4/3三分之四可以写成 1 (3/1) 一又三分之一
    15. * 程序思路说明完毕
    16. */
    17. #include <iostream>
    18. using namespace std;
    19. class Integer //整数类 类名是Integer
    20. {
    21. public:
    22. int nume; //定义分子,变量名是nume,来源于分子Numerator的缩写
    23. int deno; //定义分母,变量名是deno,来源于分母denominator的缩写
    24. int judge; //定义一个判断值,具体判断需看源码
    25. Integer(int a = 0, int b = 1) :nume(a), deno(b) {}
    26. //声明了一个构造函数,并传递了一个初始参数0和1,初始化分子nume为0,分母deno为1
    27. ~Integer() { } //声明了一个析构函数
    28. void display(); //声明了这个显示函数
    29. };
    30. class Fraction :public Integer //分数类,进行输入输出 ,类名是Fraction
    31. {
    32. public:
    33. Fraction(int a = 0, int b = 1) : Integer(a, b) { } //声明输入函数
    34. Fraction operator+ (Fraction& c);
    35. Fraction operator+ (int n);
    36. Fraction operator- (Fraction& c);
    37. Fraction operator- (int n);
    38. friend Fraction operator-(int n, Fraction& c); //重载友元函数
    39. Fraction operator* (Fraction& c);
    40. Fraction operator* (int n);
    41. Fraction operator/ (Fraction& c);
    42. friend Fraction operator/(int n, Fraction& c);
    43. Fraction operator / (int n);
    44. Fraction predigest(); //约分函数
    45. };
    46. void Integer::display()//界面设计
    47. {
    48. cout << "\t\t\t\t分数计算器"<<endl;
    49. cout << "**********************************************************************************\n" ;
    50. cout << "* 请选择功能: *\n";
    51. cout << "* A 分数与整数的四则运算 *\n";
    52. cout << "* B 整数与分数的四则运算 *\n";
    53. cout << "* C 分数与分数的四则运算 *\n";
    54. cout << "* 0 输入0退出系统 *\n";
    55. cout << "**********************************************************************************\n";
    56. }
    57. Fraction Fraction::predigest()//定义约分函数
    58. {
    59. int n, d, t, sign = 1;
    60. Fraction temp; //定义一个在约分的时候的Fraction型变量temp
    61. if (nume < 0 && deno < 0) //这是分子分母都为负的情况,负负得正,都把符号消掉
    62. {
    63. nume = -nume;
    64. deno = -deno;
    65. }
    66. if (nume > 0 && deno < 0) //这里是分母是负的,分子是正的,整体值是负的,把负号存到sign里
    67. {
    68. deno = -deno; //因为负号已经存起来,所以取正便于运算。
    69. sign = -1;
    70. }
    71. if (nume < 0 && deno > 0) //这里是分母是正的,分子是负的,整体值是负的,把负号存到sign里
    72. {
    73. nume = -nume;
    74. sign = -1;
    75. }
    76. n = nume; //分子赋值给临时局部变量n
    77. d = deno; //分母赋值给临时局部变量d
    78. int r; //辗转相除求出最大公约数 ,临时变量r是交换的中间变量
    79. //先用较小的数对较大的数取余,再用余数对较小的数求余,直到余数为零
    80. if (n < d)
    81. { //因为后面的取余语句默认n是大的,所以万一n是小的,就将其值交换
    82. t = n;
    83. n = d; //这里其实可以用algorithm库里的swap函数实现。swap(n,d);就可以省三行
    84. d = t;
    85. }
    86. r = n % d; //求一次余数
    87. while (r != 0) //如果余数不等于0,就进行辗转相除法求最大公约数
    88. {
    89. n = d;
    90. d = r;
    91. r = n % d;
    92. } //得到了d是最大公约数
    93. temp.nume = sign * (nume / d); //此时分子除最大公约数,分母也除最大公约数,同时分子加上符号,再把值传回去。就实现了约分
    94. temp.deno = deno / d; //分母也除以最大公约数,才能是约分后的分母
    95. return temp; //把约分之后的结果传回去
    96. }
    97. Fraction Fraction::operator+(Fraction& c)//重载加法运算符
    98. {
    99. Fraction temp;
    100. temp.nume = nume * c.deno + deno * c.nume;
    101. temp.deno = deno * c.deno;
    102. return temp;
    103. }
    104. Fraction Fraction::operator+ (int n)
    105. {
    106. Fraction temp;
    107. temp.nume = deno * n + nume;
    108. temp.deno = deno;
    109. return temp;
    110. }
    111. Fraction Fraction::operator-(Fraction& c)//重载减法运算符
    112. {
    113. Fraction temp;
    114. temp.nume = nume * c.deno - deno * c.nume;
    115. temp.deno = deno * c.deno;
    116. return temp;
    117. }
    118. Fraction Fraction::operator- (int n)
    119. {
    120. Fraction temp;
    121. temp.nume = deno * n - nume;
    122. temp.deno = deno;
    123. return temp;
    124. }
    125. Fraction Fraction::operator*(Fraction& c)//重载乘法运算符
    126. {
    127. Fraction temp;
    128. temp.nume = nume * c.nume; //分子乘分子分母乘分母
    129. temp.deno = deno * c.deno; //先把结果传过去,约分最后用函数实现
    130. return temp;
    131. }
    132. Fraction Fraction::operator*(int n)
    133. {
    134. Fraction temp;
    135. temp.nume = nume * n;
    136. temp.deno = deno;
    137. return temp;
    138. }
    139. Fraction operator-(int n, Fraction& c)
    140. {
    141. Fraction temp;
    142. temp.nume = c.deno * n - c.nume;
    143. temp.deno = c.deno;
    144. return temp;
    145. }
    146. Fraction Fraction::operator/(Fraction& c)//重载除法运算符
    147. {
    148. Fraction temp;
    149. temp.nume = nume * c.deno; //取倒数(分子分母互换)
    150. temp.deno = deno * c.nume; //再乘,就实现了除法
    151. return temp;
    152. }
    153. Fraction Fraction::operator/ (int n)
    154. {
    155. Fraction temp;
    156. temp.nume = nume;
    157. temp.deno = deno * n;
    158. return temp;
    159. }
    160. Fraction operator/(int n, Fraction& c)
    161. {
    162. Fraction temp;
    163. temp.nume = n * c.deno;
    164. temp.deno = c.nume;
    165. return temp;
    166. }
    167. ostream& operator<<(ostream& output, Fraction& t)//重载输出运算符
    168. {
    169. int a, b, c;
    170. a = t.nume;
    171. b = t.deno;
    172. if (a == 0 || b == 0)
    173. cout << "0" << endl;
    174. if (b == 1)
    175. cout << a << endl;
    176. if (a > b && b != 1)
    177. {
    178. c = a / b;
    179. a = a % b;
    180. cout << c;
    181. cout << "又" << a << '/' << b; //带分数
    182. }
    183. if (a<0 && -a>b && b != 1)
    184. {
    185. c = -a / b;
    186. a = -a % b;
    187. c = -c;
    188. cout << '=' << c;
    189. if (a != 0)
    190. cout << "又" << a << '/' << b;
    191. }
    192. if (t.nume > 0 && t.nume < t.deno && t.deno != 0 && t.deno != 1)
    193. output << t.nume << '/' << t.deno << endl;
    194. if (t.nume < 0 && -t.nume < t.deno && t.deno != 0 && t.deno != 1)
    195. output << "(" << t.nume << '/' << t.deno << ")" << endl;
    196. return output;
    197. }
    198. istream& operator>>(istream& input, Fraction& t)//重载输入运算符
    199. {
    200. int a, c;
    201. char b;
    202. input >> a >> b >> c;
    203. if (b == '/' && c != 0)
    204. {
    205. t.nume = a;
    206. t.deno = c;
    207. t.judge = 0;
    208. }
    209. else
    210. {
    211. t.judge = 1;
    212. cout << "输入格式错误或分母为0!请退出重新输入!" << endl;
    213. }
    214. return input;
    215. }
    216. int main()
    217. {
    218. Integer dis; //定义一个将来用来打印主界面的dis变量
    219. Fraction fracNum, fracedNum, result, real;
    220. /*
    221. * 这里的一堆变量意义如下:
    222. * fracNum(Fraction Number) 表示第一个数
    223. * fracedNum(Fracted Number) 表示第二个数
    224. * result 用来存结果
    225. * real 用来存约分之后的真分数
    226. */
    227. double m, z, n;
    228. char oprt; //定义一个操作符,操作符可以是 + - * /
    229. char selectValue; //定义一个选择值
    230. dis.display(); //执行输出函数,把页面打印出来。
    231. cout << "输入0,关闭系统,输入A,B,C进入" << endl;
    232. cin >> selectValue; //输入选择
    233. while (selectValue != '0')
    234. {
    235. cout << " 请输入:(A/B/C) :";
    236. cin >> selectValue;
    237. if (selectValue == 'A' || selectValue == 'a')//分数与正整数运算
    238. {
    239. do
    240. {
    241. cout << endl << " 请输入一个分数: ";
    242. cin >> fracNum;
    243. } while (fracNum.judge == 1);
    244. cout << endl << " 请输入运算符: ";
    245. cin >> oprt;
    246. cout << endl << " 请输入一个整数: ";
    247. cin >> z;
    248. if (oprt == '+')
    249. result = fracNum + z;
    250. if (oprt == '-')
    251. result = fracNum - z;
    252. if (oprt == '*')
    253. result = fracNum * z;
    254. if (oprt == '/')
    255. result = fracNum / z;
    256. real = result.predigest(); //这里result并不是最后一步结果变量,约分之后的real才是最终输出的值
    257. cout << " 运算时的规范形式为: " << fracNum << oprt << z << '=' << real << endl << endl;
    258. }
    259. if (selectValue == 'B' || selectValue == 'b')//正整数与分数运算
    260. {
    261. cout << endl << endl << " 请输入一个整数: ";
    262. cin >> z;
    263. cout << endl << " 请输入运算符: ";
    264. cin >> oprt;
    265. do
    266. {
    267. cout << endl << " 请输入一个分数: ";
    268. cin >> fracedNum;
    269. } while (fracedNum.judge == 1);
    270. if (oprt == '+')
    271. result = fracedNum + z;
    272. if (oprt == '-')
    273. result = fracedNum - z;
    274. if (oprt == '*')
    275. result = fracedNum * z;
    276. if (oprt == '/')
    277. result = fracedNum / z;
    278. real = result.predigest();
    279. cout << " 运算时的规范形势为: " << z << oprt << fracedNum << '=' << real << endl << endl;
    280. }
    281. if (selectValue == 'C' || selectValue == 'c')//分数与分数运算
    282. {
    283. do
    284. {
    285. cout << endl << " 请输入一个分数: ";
    286. cin >> fracNum;
    287. } while (fracNum.judge == 1);
    288. cout << endl << " 请输入运算符: ";
    289. cin >> oprt;
    290. do
    291. {
    292. cout << endl << " 请输入一个分数: ";
    293. cin >> fracedNum;
    294. } while (fracedNum.judge == 1);
    295. if (oprt == '+')
    296. result = fracNum + fracedNum;
    297. if (oprt == '-')
    298. result = fracNum - fracedNum;
    299. if (oprt == '*')
    300. result = fracNum * fracedNum;
    301. if (oprt == '/')
    302. result = fracNum / fracedNum;
    303. real = result.predigest();
    304. cout << " 运算时的规范形势为: " << fracNum << oprt << fracedNum << '=' << real << endl << endl;
    305. }
    306. }
    307. return 0;
    308. }