游荡知乎这么久,甚是仰慕V神。遂开始造轮子之路,由于新手实力较菜。顾从简单的大整数的入门。
功能实现分析:
1. 能用字符串, 长整型(long long or _int64)构造出此BigInteger.
2. 具有正负数之分(整这个整了好一会)
3. 实现基本运算 (c,d,e)尚未实现
a 加 b 减
c 乘 d 除
e 取余
4.输入,输出运算符的重载
类整体架构如下。
1 class BigInt { 2 friend ostream& operator<<(ostream &os, const BigInt &bi); 3 friend istream& operator>>(istream &is, BigInt &bi); 4 public: 5 BigInt() = default; 6 BigInt(string in); 7 BigInt(istream &in); 8 BigInt(long long in); 9 void setPositive(bool flag); 10 bool operator<(const BigInt &bi) const; 11 bool operator>(const BigInt &bi) const; 12 bool operator==(const BigInt &bi) const; 13 void valueOf(string in); 14 BigInt operator+(const BigInt &bi); 15 BigInt operator-(const BigInt &bi);16 BigInt operator*(const BigInt &bi); 17 private: 18 //以下为忽略符号的运算 符号问题在重载运算符中判断. 19 BigInt add(const BigInt &bi) const; 20 BigInt minus(const BigInt &bi) const; //忽视符号的减法 大的数要为this 21 BigInt multiply(short t, int k) const; // t只能是个位数 22 bool less(const BigInt &bi) const; 23 bool equal(const BigInt &bi) const; 24 25 //读取构造 26 void read(string in); 27 28 bool positive = true; 29 vector<short> num; //存储大数的每一位 逆序 从个位开始 30 };
类API实现如下:
1 bool BigInt::equal(const BigInt &bi) const { 2 if (this->num.size() != bi.num.size()) 3 return false; 4 for (decltype(bi.num.size()) i = 0; i < bi.num.size(); i++) { 5 if (this->num[i] != bi.num[i]) 6 return false; 7 } 8 return true; 9 } 10 BigInt BigInt::operator+(const BigInt &bi) { 11 if (this->positive == bi.positive) { 12 //存在拷贝构造 性能问题?? 13 BigInt ans = add(bi); 14 ans.setPositive(bi.positive); 15 return ans; 16 } 17 else { 18 BigInt ans; 19 if (this->less(bi)) { 20 ans = bi.minus(*this); 21 ans.setPositive(bi.positive); 22 } 23 else if (this->equal(bi)) { 24 ans.num.push_back(0); 25 return ans; 26 } 27 else { 28 ans = this->minus(bi); 29 ans.setPositive(this->positive); 30 } 31 return ans; 32 } 33 34 } 35 BigInt BigInt::operator-(const BigInt &bi) { 36 if (this->positive == bi.positive) { 37 BigInt ans; 38 if (this->less(bi)) { 39 ans = bi.minus(*this); 40 ans.setPositive(!this->positive); 41 } 42 else if (this->equal(bi)) { 43 ans.num.push_back(0); 44 } 45 else { 46 ans = this->minus(bi); 47 ans.setPositive(this->positive); 48 } 49 return ans; 50 } 51 else { 52 BigInt ans = this->add(bi); 53 ans.setPositive(this->positive); 54 return ans; 55 } 56 } 57 BigInt BigInt::operator*(const BigInt &bi) { 58 if (*this == *(new BigInt(0)) || bi == *(new BigInt(0))) { 59 BigInt ans; 60 ans.num.push_back(0); 61 return ans; 62 } 63 else { 64 int t = 0; 65 // 使用隐式转换 安全? 66 BigInt ans = 0; 67 for (decltype(num.size()) i = 0; i < num.size(); i++) { 68 ans = ans + bi.multiply(i, t); 69 t++; 70 } 71 if (this->positive != bi.positive) { 72 ans.setPositive(false); 73 } 74 return ans; 75 } 76 } 77 void BigInt::setPositive(bool flag) { 78 this->positive = flag; 79 } 80 bool BigInt::operator==(const BigInt &bi) const { 81 if (this->positive != bi.positive) 82 return false; 83 else { 84 if (this->num.size() != bi.num.size()) 85 return false; 86 for (decltype(bi.num.size()) i = 0; i < bi.num.size(); i++) { 87 if (this->num[i] != bi.num[i]) 88 return false; 89 } 90 return true; 91 } 92 } 93 bool BigInt::operator<(const BigInt &bi) const { 94 if (this->positive == true) { 95 if (bi.positive == false) //this为正 bi为负 96 return false; 97 else { //this与bi同为正 98 if (this->num.size() > bi.num.size()) //长度长的大 99 return false; 100 else if (this->num.size() < bi.num.size()) 101 return true; 102 bool flag = false; 103 //一样长的时候比较为一位 注意要逆序比较 以为数字的首位存在容器的最后一位 104 for (int i = this->num.size() - 1; i >= 0; i--) { 105 if (this->num[i] > bi.num[i]) { 106 flag = true; 107 break; 108 } 109 } 110 return flag; 111 112 } 113 } 114 else { // 跟以上反过来就行了 115 if (bi.positive == true) //this为负 bi为正 116 return true; 117 else { //同为负数时 118 if (this->num.size() > bi.num.size()) 119 return true; 120 else if (this->num.size() < bi.num.size()) 121 return false;; 122 bool flag = false; 123 for (int i = this->num.size() - 1; i >= 0; i--) { 124 if (this->num[i] < bi.num[i]) { 125 flag = true; 126 break; 127 } 128 } 129 return !flag; 130 } 131 } 132 133 } 134 bool BigInt::operator>(const BigInt &bi) const { 135 if (*this < bi) 136 return false; 137 else if (*this == bi) 138 return false; 139 else 140 return true; 141 } 142 istream& operator>>(istream &in, BigInt &bi) { 143 string input; //读取所创建的大数 144 in >> input; 145 while (!bi.num.empty()) 146 bi.num.clear(); 147 try { 148 if (input[0] == ‘-‘) 149 bi.positive = false; 150 else 151 bi.positive = true; 152 for (int i = input.size() - 1; i >= 0; i--) { 153 if (0 == i && !bi.positive) 154 break; 155 if (input[i] < ‘0‘ || input[i] > ‘9‘) 156 throw runtime_error("You should input a positive integer."); 157 bi.num.push_back(input[i] - ‘0‘); 158 } 159 } 160 catch (runtime_error e) { 161 std::cerr << e.what() << endl; 162 } 163 return in; 164 } 165 ostream& operator<<(ostream &os, const BigInt &bi) { 166 // 逆序输出 167 if (!bi.positive) 168 os << "-"; 169 for (int i = bi.num.size() - 1; i >= 0; i--) { 170 os << bi.num[i]; 171 } 172 return os; 173 }
今天先撸到这里。 让我再想想乘除的实现方法吧
Vane_Tse On the Road. 2014-06-18 21:42:56
BigInteger in Cpp (造轮子大法第一波) 未完成版本
时间: 2024-10-07 12:04:08