写了5个小时,C++面向对象的东西都不会写了。。。以后要多写C++少写python。。。关于读入字符串处理的那部分写得太挫就不放了。
#include "List.hpp"
List
1 #pragma once 2 #include <cstdio> 3 #include <cassert> 4 5 namespace kirai { 6 template<class type> class List { 7 private: 8 typedef struct ListNode { 9 type data; 10 ListNode* pre; 11 ListNode* next; 12 ListNode() : data(data) { pre = NULL; next = NULL; } 13 ListNode(const type& dd, ListNode*& pp, ListNode*& nn) : 14 data(dd), pre(pp), next(nn) {} 15 }ListNode; 16 ListNode* head; 17 public: 18 List() : head(new ListNode()) { head->pre = head->next = head; }; 19 int size() const; 20 bool empty() const; 21 void push_back(const type&); 22 type last() const; 23 void pop_back(); 24 void modifyLast(const type&); 25 void insert(const type& ele, int idx); 26 type get(int idx) const; 27 type& operator [](int idx); 28 type remove(int idx); 29 void modify(const type& ele, int idx); 30 int find(const type&) const; 31 void clear(); 32 ~List() = default; 33 }; 34 35 template<class type> 36 int List<type>::size() const { 37 int tot = 0; 38 ListNode* p = head->next; 39 while (p != head) { 40 tot++; 41 p = p->next; 42 } 43 return tot; 44 } 45 46 template<class type> 47 bool List<type>::empty() const { 48 return head == head->next ? 1 : 0; 49 } 50 51 template<class type> 52 void List<type>::push_back(const type& element) { 53 ListNode* p = new ListNode(element, head->pre, head); 54 head->pre = head->pre->next = p; 55 } 56 57 template<class type> 58 type List<type>::last() const { 59 assert(!empty()); 60 return head->pre->data; 61 } 62 63 template<class type> 64 void List<type>::pop_back() { 65 assert(!empty()); 66 ListNode* p = head->pre->pre; 67 delete head->pre; 68 head->pre = p; 69 p->next = head; 70 } 71 72 template<class type> 73 void List<type>::modifyLast(const type& element) { 74 assert(!empty()); 75 head->pre->data = element; 76 } 77 78 template<class type> 79 void List<type>::insert(const type& element, int idx) { 80 idx++; 81 assert(idx > 0 && idx <= size() + 1); 82 ListNode* p = head; 83 while (idx--) p = p->next; 84 ListNode* cur = new ListNode(element, p->pre, p); 85 p->pre = p->pre->next = cur; 86 } 87 88 template<class type> 89 type List<type>::get(int idx) const { 90 idx++; 91 assert(!empty() && idx > 0 && idx <= size()); 92 ListNode* p = head->next; 93 while (--idx) p = p->next; 94 return p->data; 95 } 96 template<class type> 97 type& List<type>::operator [](int idx) { 98 idx++; 99 assert(!empty() && idx > 0 && idx <= size()); 100 ListNode* p = head->next; 101 while (--idx) p = p->next; 102 return p->data; 103 } 104 template<class type> 105 type List<type>::remove(int idx) { 106 idx++; 107 assert(!empty() && idx > 0 && idx <= size()); 108 ListNode* p = head->next; 109 while (--idx) p = p->next; 110 p->pre->next = p->next; 111 p->next->pre = p->pre; 112 type d = p->data; 113 delete p; 114 return d; 115 } 116 117 template<class type> 118 void List<type>::modify(const type& ele, int idx) { 119 idx++; 120 assert(!empty() && idx > 0 && idx <= size()); 121 ListNode* p = head->next; 122 while (--idx) p = p->next; 123 p->data = ele; 124 } 125 126 template<class type> 127 int List<type>::find(const type& ele) const { 128 ListNode* p = head->next; 129 int idx = 0; 130 while (p != head) { 131 if (p->data == ele) return idx; 132 p = p->next; 133 idx++; 134 } 135 return -1; 136 } 137 template<class type> 138 void List<type>::clear() { 139 assert(!empty()); 140 } 141 }
List.hpp
1 #pragma once 2 #include "lib/List" 3 4 using kirai::List; 5 6 #define positive 1 7 #define negative 0 8 9 class BigInteger { 10 public: 11 BigInteger() { _symbol = positive; } 12 BigInteger(const char*); 13 ~BigInteger() = default; 14 BigInteger add(const BigInteger&); 15 BigInteger sub(const BigInteger&); 16 bool symbol()const { return this->_symbol; } 17 void setSymbol(bool isPositive) { this->_symbol = isPositive; } 18 void setNum(List<short> s) { data = s; } 19 void show(); 20 int cmp(const BigInteger&); 21 BigInteger addTwoPositive(const BigInteger&, const BigInteger&); 22 BigInteger bigSubSmall(const BigInteger&, const BigInteger&); 23 bool _symbol; 24 List<short> data; 25 };
BigInteger.h
1 #include "BigInteger.h" 2 #include <cassert> 3 #include <iostream> 4 #include <iomanip> 5 6 #define positive 1 7 #define negative 0 8 9 int BigInteger::cmp(const BigInteger& A) { 10 // 比较两个数的绝对值大小,如果this大返回1,A大返回-1,相等返回0 11 int la = this->data.size(); 12 int lb = A.data.size(); 13 if (la > lb) return 1; 14 if (la < lb) return -1; 15 // 长度相等的时候,从高位比到低位 16 for (int i = la - 1; i >= 0; i--) { 17 if (this->data.get(i) > A.data.get(i)) return 1; 18 if (this->data.get(i) < A.data.get(i)) return -1; 19 } 20 return 0; 21 } 22 23 BigInteger BigInteger::add(const BigInteger& B) { 24 assert(!this->data.empty() && !B.data.empty()); 25 // 拷贝 26 BigInteger ta = *this; 27 BigInteger tb = B; 28 BigInteger ans; 29 30 // 全都是负数到时候,传入参数的时候做相加操作 31 if (negative == this->symbol() && negative == B.symbol()) { 32 ta.setSymbol(positive); tb.setSymbol(positive); 33 ans = addTwoPositive(ta, tb); 34 ans.setSymbol(negative); 35 } 36 // 全都是正数的时候,直接相加 37 if (positive == this->symbol() && positive == B.symbol()) { 38 ans = addTwoPositive(ta, tb); 39 ans.setSymbol(positive); 40 } 41 // 一正一负的情况,比较一下绝对值大小 42 else { 43 int flag; 44 // A正B负 45 if (positive == this->symbol() && negative == B.symbol()) { 46 flag = this->cmp(B); 47 if (flag == 1) { //相当于非负数减法 48 ta.setSymbol(positive); tb.setSymbol(positive); 49 ans = bigSubSmall(ta, tb); 50 ans.setSymbol(positive); 51 } 52 if (flag == 0) { //直接返回0即可 53 ta.setSymbol(positive); tb.setSymbol(positive); 54 ans.data.push_back(0); 55 ans.setSymbol(positive); 56 } 57 if (flag == -1) { //相当于负数的绝对值减正数,结果为负 58 ta.setSymbol(positive); tb.setSymbol(positive); 59 ans = bigSubSmall(tb, ta); 60 ans.setSymbol(negative); 61 } 62 } 63 // A负B正 64 if (negative == this->symbol() && positive == B.symbol()) { 65 flag = this->cmp(B); 66 if (flag == 1) { //相当于负数的绝对值减正数,结果为负 67 ta.setSymbol(positive); tb.setSymbol(positive); 68 ans = bigSubSmall(ta, tb); 69 ans.setSymbol(negative); 70 } 71 if (flag == 0) { //直接返回0即可 72 ta.setSymbol(positive); tb.setSymbol(positive); 73 ans.data.push_back(0); 74 ans.setSymbol(positive); 75 } 76 if (flag == -1) { //相当于非负数减法 77 ta.setSymbol(positive); tb.setSymbol(positive); 78 ans = bigSubSmall(tb, ta); 79 ans.setSymbol(positive); 80 } 81 } 82 } 83 return ans; 84 } 85 86 BigInteger BigInteger::sub(const BigInteger& B) { 87 assert(!this->data.empty() && !B.data.empty()); 88 // 拷贝 89 BigInteger* A = const_cast<BigInteger*>(this); 90 BigInteger ta = *this; 91 BigInteger tb = B; 92 BigInteger ans; 93 94 // A正B负,做加法,结果为正 95 if (positive == this->symbol() && negative == B.symbol()) { 96 ta.setSymbol(positive); tb.setSymbol(positive); 97 addTwoPositive(ta, tb); 98 ans.setSymbol(positive); 99 } 100 // A负B正,做加法,结果为负 101 if (negative == this->symbol() && positive == B.symbol()) { 102 ta.setSymbol(positive); tb.setSymbol(positive); 103 addTwoPositive(ta, tb); 104 ans.setSymbol(negative); 105 } 106 else { 107 int flag; 108 // 两个数都是正 109 if (positive == this->symbol() && positive == B.symbol()) { 110 flag = this->cmp(B); 111 if (flag == 1) { //相当于大减小,结果为正 112 ta.setSymbol(positive); tb.setSymbol(positive); 113 ans = bigSubSmall(ta, tb); 114 ans.setSymbol(positive); 115 } 116 if (flag == 0) { //直接返回0即可 117 ta.setSymbol(positive); tb.setSymbol(positive); 118 ans.data.push_back(0); 119 ans.setSymbol(positive); 120 } 121 if (flag == -1) { //相当于小减大,反着减结果为负 122 ta.setSymbol(positive); tb.setSymbol(positive); 123 ans = bigSubSmall(tb, ta); 124 ans.setSymbol(negative); 125 } 126 } 127 //两个数都是负 128 if (negative == this->symbol() && negative == B.symbol()) { 129 ta.setSymbol(positive); tb.setSymbol(positive); 130 flag = this->cmp(B); 131 if (flag == 1) { //相当于大的减小的,结果为负 132 ta.setSymbol(positive); tb.setSymbol(positive); 133 ans = bigSubSmall(ta, tb); 134 ans.setSymbol(negative); 135 } 136 if (flag == 0) { //直接返回0即可 137 ta.setSymbol(positive); tb.setSymbol(positive); 138 ans.data.push_back(0); 139 ans.setSymbol(positive); 140 } 141 if (flag == -1) { //相当于小的减大的,结果为正 142 ta.setSymbol(positive); tb.setSymbol(positive); 143 ans = bigSubSmall(tb, ta); 144 ans.setSymbol(positive); 145 } 146 } 147 } 148 return ans; 149 } 150 151 // A + B 全正 152 BigInteger BigInteger::addTwoPositive(const BigInteger& A, const BigInteger& B) { 153 using namespace std; 154 BigInteger ans; 155 int la = A.data.size(); 156 int lb = B.data.size(); 157 int len = la < lb ? la : lb; 158 for (int i = 0; i < len; i++) { 159 ans.data.push_back(0); 160 ans.data[i] = A.data.get(i) + B.data.get(i); 161 } 162 for (int i = len; i < la; i++) { 163 ans.data.push_back(0); 164 ans.data[i] = A.data.get(i); 165 } 166 for (int i = len; i < lb; i++) { 167 ans.data.push_back(0); 168 ans.data[i] = A.data.get(i); 169 } 170 // 处理进位 171 len = la > lb ? la : lb; 172 bool up = 0; // 进位标记 173 short cur; 174 for (int i = 0; i < len; i++) { 175 if (up == 1) { 176 ans.data[i] += cur; 177 up = 0; 178 } 179 if (ans.data.get(i) >= 10000) { 180 cur = ans.data[i] / 10000; 181 short tmp = ans.data[i] % 10000; 182 ans.data[i] = tmp; 183 up = 1; 184 } 185 else up = 0; 186 } 187 if (up) { //最后一位还需要进位 188 while (cur) { 189 ans.data.push_back(cur); 190 cur /= 10000; 191 } 192 } 193 return ans; 194 195 } 196 197 // A - B (A > B) 全正 198 BigInteger BigInteger::bigSubSmall(const BigInteger& A, const BigInteger& B) { 199 BigInteger ans; 200 int la = A.data.size(); 201 int lb = B.data.size(); 202 int len = la < lb ? la : lb; 203 for (int i = 0; i < len; i++) { 204 ans.data.push_back(0); 205 ans.data[i] = A.data.get(i) - B.data.get(i); 206 } 207 for (int i = len; i < la; i++) { 208 ans.data.push_back(0); 209 ans.data[i] = A.data.get(i); 210 } 211 len = la > lb ? la : lb; 212 // 处理借位 213 bool down = 0; 214 for (int i = 0; i < len; i++) { 215 if (down == 1) { 216 ans.data[i] -= 1; 217 down = 0; 218 } 219 if (ans.data[i] < 0) { 220 ans.data[i] += 10000; 221 down = 1; 222 } 223 else down = 0; 224 } 225 return ans; 226 } 227 228 void BigInteger::show() { 229 using namespace std; 230 int len = data.size(); 231 if (this->symbol() == negative) { 232 cout << "-"; 233 } 234 cout << data[len - 1]; 235 if (len == 1) { 236 cout << endl; 237 return; 238 } 239 for (int i = len - 2; i >= 0; i--) { 240 cout << "," << std::setw(3) << std::setfill(‘0‘) << data[i]; 241 } 242 cout << endl; 243 }
BigInteger.cpp
时间: 2024-10-10 07:05:33