自从学习了C++面向对象编程相关基础语法后,苦于没有相应的习题来练习,偶然遇到了大佬华师数据学院·王嘉宁分享的50道习题,比较基础,但是确实会给我这样的初学者一个可以简单上手的机会。
接下来我打算用这个暑假的时间来完成一共50道题目的解答,当然会参考大佬给出的解答,但是更多的会加入自己的一些想法,为了自己立的flag不会倒,我会把所有的代码及时分享出来,有空闲也会详细说明一些语法,希望与大家共勉。
下面是第一题:分数相加
#ifndef _FRACT_HPP_ #define _FRACT_HPP_ #includeusing uint_t = unsigned int; class Fract { private: uint_t fenzi, fenmu; // 分子分母均为正数表示 char sign; // 正负号,默认为'+' uint_t gcd(uint_t, uint_t) const; // 最大公约数 uint_t lcm(uint_t, uint_t) const; // 最小公倍数 public: explicit Fract(uint_t a = 0, uint_t b = 1, char s = '+'); // 构造函数参数默认值写入函数声明中,且使用explicit禁用复制初始化 void add(const Fract&); void sub(const Fract&); Fract operator+(const Fract&) const; Fract operator-(const Fract&) const; void show() const; }; // 构造函数,检查分子分母是否最简 Fract::Fract(uint_t a, uint_t b, char s) : fenzi(a), fenmu(b), sign(s) { uint_t init_gcd = gcd(fenzi, fenmu); // 将分子分母化为最简 if (init_gcd != 0) { fenzi = fenzi / init_gcd; fenmu = fenmu / init_gcd; } } // 最大公约数 uint_t Fract::gcd(uint_t m, uint_t n) const { uint_t k = m < n ? m : n; for (; k > 0; --k) { if (m % k == 0 && n % k == 0) { break; } } return k; } // 最小公倍数: 两数相乘后除以最大公约数 uint_t Fract::lcm(uint_t m, uint_t n) const { return m * n / gcd(m, n); } // 分数加法 void Fract::add(const Fract& x) { uint_t init_lcm = lcm(this->fenmu, x.fenmu); int temp_fenzi; // 如果x符号为-,则分子相减 if (x.sign == '+') { temp_fenzi = this->fenzi * init_lcm / this->fenmu + x.fenzi * init_lcm / x.fenmu; } else { temp_fenzi = this->fenzi * init_lcm / this->fenmu - x.fenzi * init_lcm / x.fenmu; } if (temp_fenzi < 0) { // 结果为-,则修改符号为- this->fenzi = temp_fenzi * -1; this->sign = '-'; } else { this->fenzi = temp_fenzi; this->sign = '+'; } this->fenmu = init_lcm; // 将分子分母化为最简 uint_t init_gcd = gcd(fenzi, fenmu); if (init_gcd != 0) { fenzi = fenzi / init_gcd; fenmu = fenmu / init_gcd; } } // 分数减法 void Fract::sub(const Fract& x) { char s = x.sign == '+' ? '-' : '+'; // 获取x的相反符号 Fract y(x.fenzi, x.fenmu, s); this->add(y); } // 运算符+重载 Fract Fract::operator+(const Fract& x) const { Fract z(this->fenzi, this->fenmu, this->sign); z.add(x); return z; } // 运算符-重载 Fract Fract::operator-(const Fract& x) const { Fract z(this->fenzi, this->fenmu, this->sign); z.sub(x); return z; } // 分数显示 void Fract::show() const { char s = this->sign == '+' ? ' ':'-'; if (fenzi % fenmu == 0) { std::cout << s << fenzi / fenmu << std::endl; } else { std::cout << s << this->fenzi << '/' << this->fenmu << std::endl; } } #endif



