Advertisement
blufzzz

Fivt_4/task-A/07.12.2017

Dec 7th, 2017
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.81 KB | None | 0 0
  1. #ifndef FIVT_4_BIGINTEGER_H
  2. #define FIVT_4_BIGINTEGER_H
  3.  
  4. #include <iostream>
  5. #include <vector>
  6. #include <string>
  7.  
  8. const unsigned int BASE = 10;
  9.  
  10. class BigInteger {
  11. public:
  12. BigInteger(const std::vector<int>& _numbers, bool _is_positive);
  13. BigInteger(int integer_value);
  14. BigInteger();
  15. void Print() const;
  16. bool GetIsPositive() const;
  17. size_t GetNumberOfDigits() const;
  18. std::vector<int> GetVectorOfDigits() const;
  19. void SetIsPositive(bool sign);
  20. void MultiplyOnBase();
  21. void DeleteLeadZeros();
  22.  
  23. BigInteger operator + (const BigInteger& other) const;
  24. BigInteger operator - (const BigInteger& other) const;
  25. BigInteger operator - ();
  26. BigInteger operator * (const BigInteger& other) const;
  27. BigInteger operator / (const BigInteger& other) const;
  28. BigInteger operator % (const BigInteger& other) const;
  29.  
  30. void operator += (const BigInteger& other);
  31. void operator -= (const BigInteger& other);
  32. void operator *= (const BigInteger& other);
  33. void operator /= (const BigInteger& other);
  34.  
  35. BigInteger operator++() const; // prefix-form
  36. BigInteger operator++(int notused) const; // postfix-form
  37. BigInteger operator--() const; // prefix-form
  38. BigInteger operator--(int notused) const; // postfix-form
  39.  
  40. bool operator==(const BigInteger& other) const;
  41. bool operator!=(const BigInteger& other) const;
  42. bool operator<=(const BigInteger& other) const;
  43. bool operator>=(const BigInteger& other) const;
  44. bool operator<(const BigInteger& other) const;
  45. bool operator>(const BigInteger& other) const;
  46.  
  47. // input - output
  48. friend std::ostream &operator<<(std::ostream& stream, const BigInteger& big_integer);
  49. friend std::istream &operator>>(std::istream& stream, BigInteger& big_integer);
  50.  
  51. // type conversion
  52. operator int();
  53. operator bool();
  54.  
  55. std::string toString();
  56. private:
  57. std::vector<int> vector_of_digits;
  58. bool is_positive;
  59. bool CompareByAbs(const BigInteger& other) const;
  60. };
  61.  
  62.  
  63.  
  64.  
  65. BigInteger::BigInteger(const std::vector<int>& _numbers, bool _is_positive) {
  66. vector_of_digits = _numbers;
  67. is_positive = _is_positive;
  68. }
  69.  
  70.  
  71.  
  72. BigInteger::BigInteger(int integer_value) {
  73. std::vector<int> digits;
  74. is_positive = (integer_value >= 0);
  75. integer_value = ( integer_value < 0 )? -integer_value : integer_value;
  76. if ( integer_value == 0 ) {
  77. digits.push_back(0);
  78. } else {
  79. int current_rest = 0;
  80. int prev_rest = 0;
  81. unsigned long long charge = BASE;
  82. while (true) {
  83. prev_rest = current_rest;
  84. current_rest = integer_value % charge;
  85. digits.push_back((current_rest - prev_rest) / (charge / BASE));
  86. if (current_rest == integer_value) {
  87. break;
  88. }
  89. charge *= BASE;
  90. }
  91. }
  92. vector_of_digits = digits;
  93. }
  94.  
  95.  
  96.  
  97.  
  98. BigInteger::BigInteger() {
  99. std::vector<int> digits;
  100. vector_of_digits = digits;
  101. is_positive = true;
  102. }
  103.  
  104.  
  105.  
  106. std::vector<int> BigInteger::GetVectorOfDigits() const {
  107. return vector_of_digits;
  108. }
  109.  
  110.  
  111.  
  112. bool BigInteger::GetIsPositive() const {
  113. return is_positive;
  114. }
  115.  
  116.  
  117. BigInteger BigInteger::operator+(const BigInteger &other) const {
  118.  
  119. // this is positive, other is negative
  120. if (this->GetIsPositive() && !other.GetIsPositive()) { // (+a) + (-b)
  121. BigInteger other_positive = other; // MEMORY!
  122. other_positive.SetIsPositive(true);
  123. return (*this - other_positive);
  124.  
  125. // this is negative, other is positive
  126. } else if (!this->GetIsPositive() && other.GetIsPositive()) { // (-a) + (+b)
  127. BigInteger this_positive = *this; // MEMORY!
  128. this_positive.SetIsPositive(true);
  129. return (other - this_positive);
  130.  
  131. // this & other are negative
  132. } else if (!this->GetIsPositive() && !other.GetIsPositive()) {
  133. BigInteger this_positive = *this; // MEMORY!
  134. this_positive.SetIsPositive(true);
  135. BigInteger other_positive = other; // MEMORY!
  136. other_positive.SetIsPositive(true);
  137. return -(this_positive + other_positive);
  138.  
  139. // both operands are positive
  140. } else {
  141.  
  142. auto other_vector_of_numbers = other.GetVectorOfDigits();
  143. std::vector<int> result;
  144. size_t n = vector_of_digits.size();
  145. size_t m = other_vector_of_numbers.size();
  146.  
  147. int to_next_charge = 0;
  148. for (size_t i = 0; i < n || i < m; ++i) {
  149. int rest = 0;
  150. int number = 0;
  151.  
  152. number = ((i < m)? other_vector_of_numbers[i]:0) + ((i < n)? vector_of_digits[i]:0) + to_next_charge;
  153. rest = number%BASE;
  154. if ( number >= BASE) {
  155. to_next_charge = 1;
  156. number = rest;
  157. } else {
  158. to_next_charge = 0;
  159. }
  160.  
  161. result.push_back(number);
  162. }
  163.  
  164. if (to_next_charge != 0) {
  165. result.push_back(to_next_charge);
  166. }
  167.  
  168. return {result, true};
  169. }
  170. }
  171.  
  172.  
  173.  
  174. BigInteger BigInteger::operator-(const BigInteger &other) const {
  175.  
  176. // this is positive, other is negative
  177. if (this->GetIsPositive() && !other.GetIsPositive()) {
  178. BigInteger other_positive = other; // (+a) - (-b)
  179. other_positive.SetIsPositive(true);
  180. return (*this + other_positive);
  181.  
  182. // this is negative, other is positive
  183. } else if (!this->GetIsPositive() && other.GetIsPositive()) { // (-a) - (+b)
  184. BigInteger this_positive = *this; // MEMORY!
  185. this_positive.SetIsPositive(true);
  186. BigInteger other_positive = other; // MEMORY!
  187. other_positive.SetIsPositive(true);
  188. return -(this_positive + other_positive); // -((+a) + (+b))
  189.  
  190. // this & other are negative
  191. } else if (!this->GetIsPositive() && !other.GetIsPositive()) { //(-a) - (-b)
  192. BigInteger this_positive = *this; // MEMORY!
  193. this_positive.SetIsPositive(true);
  194. BigInteger other_positive = other; // MEMORY!
  195. other_positive.SetIsPositive(true);
  196. return (other_positive - this_positive);
  197.  
  198. // both operands are positive
  199. } else { //(+a) - (+b)
  200. std::vector<int> result;
  201. // из большего - меньшее
  202. if ( *this > other ) {
  203.  
  204. auto other_vector_of_numbers = other.GetVectorOfDigits();
  205.  
  206. size_t n = vector_of_digits.size();
  207. size_t m = other_vector_of_numbers.size();
  208.  
  209. int to_next_charge = 0;
  210. int number = 0;
  211.  
  212. for (size_t i = 0; i < n || i < m; ++i) {
  213. number = vector_of_digits[i] - ((i < m)? other_vector_of_numbers[i]:0) - to_next_charge;
  214. if (number < 0) {
  215. result.push_back(number + BASE);
  216. to_next_charge = 1;
  217. } else {
  218. result.push_back(number);
  219. to_next_charge = 0;
  220. }
  221. }
  222.  
  223. // убираем нули в конце
  224. while (result.back() == 0) {
  225. result.pop_back();
  226. }
  227.  
  228. return {result, true};
  229.  
  230. // сводим к вычитанию из большего меньшее
  231. } else if (*this == other) {
  232. result.push_back(0);
  233. return {result, true};
  234. } else {
  235. return -(other - *this);
  236. }
  237. }
  238. }
  239.  
  240.  
  241.  
  242. BigInteger BigInteger::operator-() {
  243. this->is_positive = false;
  244. return *this;
  245. }
  246.  
  247.  
  248.  
  249. BigInteger BigInteger::operator*(const BigInteger &other) const {
  250.  
  251. size_t n = this->GetNumberOfDigits();
  252. size_t m = other.GetNumberOfDigits();
  253.  
  254. // умножение длинного на короткое
  255. if ( n >= m ) {
  256.  
  257. std::vector<int> this_vector = this->GetVectorOfDigits();
  258. std::vector<int> other_vector = other.GetVectorOfDigits();
  259.  
  260. bool result_sign = this->GetIsPositive() & other.GetIsPositive();
  261.  
  262. std::vector<BigInteger> parts;
  263. for (int j = 0; j < m; ++j) { // идем по короткому
  264. int to_next_charge = 0;
  265. std::vector<int> new_part(n + j);
  266. for (int i = 0; i < n; ++i) { // по длинному
  267.  
  268. int value = (other_vector[j] * this_vector[i]) + to_next_charge;
  269. int rest = value % BASE;
  270.  
  271. if ( rest < value ) { //число больше 10
  272. to_next_charge = (value - rest)/BASE;
  273. } else {
  274. to_next_charge = 0;
  275. }
  276. new_part[i + j] = rest;
  277.  
  278. }
  279.  
  280. if ( to_next_charge > 0 ) {
  281. new_part.push_back(to_next_charge);
  282. }
  283.  
  284. parts.push_back({new_part,true});
  285. }
  286.  
  287. BigInteger result = parts[0];
  288. for(int i = 1; i < parts.size(); ++i) {
  289. result += parts[i];
  290. }
  291.  
  292. result.DeleteLeadZeros();
  293.  
  294. return result;
  295.  
  296. } else {
  297. return (other * (*this));
  298. }
  299.  
  300. }
  301.  
  302.  
  303. void BigInteger::MultiplyOnBase() {
  304. vector_of_digits.insert(vector_of_digits.begin(),0);
  305. }
  306.  
  307.  
  308.  
  309. void BigInteger::DeleteLeadZeros() {
  310. while (vector_of_digits.back() == 0 && vector_of_digits.size() > 1) {
  311. vector_of_digits.pop_back();
  312. }
  313. }
  314.  
  315.  
  316. BigInteger BigInteger::operator/(const BigInteger& other) const {
  317.  
  318. bool result_sign = this->GetIsPositive() & other.GetIsPositive();
  319. BigInteger other_positive = {other.GetVectorOfDigits(), true};
  320. BigInteger this_positive = {this->GetVectorOfDigits(), true};
  321.  
  322.  
  323. std::vector<int> result_vector;
  324.  
  325. if (other_positive > this_positive) {
  326. result_vector.push_back(0);
  327. return {result_vector, true};
  328.  
  329. } else if (other_positive == this_positive) {
  330. result_vector.push_back(1);
  331. return {result_vector, result_sign};
  332.  
  333. } else { //this > other // what if this == {0}
  334.  
  335. size_t n = this->GetNumberOfDigits();
  336. result_vector.resize(n); // число разрядов в частном не больше чем в делимом
  337. std::vector<int> this_vector = this->GetVectorOfDigits();
  338. BigInteger current_value;
  339.  
  340. for (int i = n - 1; i >= 0; i--) {
  341.  
  342. current_value.MultiplyOnBase();
  343. current_value.vector_of_digits[0] = this_vector[i]; //?? private
  344.  
  345. // подбираем максимальное число x, такое что other * attempt <= curent_value
  346. for (int l = 0; l <= BASE; ++l) {
  347.  
  348. BigInteger attempt({l}, true);
  349. BigInteger cur = other_positive * attempt;
  350.  
  351. if (cur > current_value) {
  352. result_vector[i] = l - 1;
  353. current_value = current_value - other_positive * BigInteger({l - 1}, true);
  354. current_value.DeleteLeadZeros();
  355. break;
  356. }
  357. }
  358. }
  359.  
  360. BigInteger result {result_vector, result_sign};
  361. result.DeleteLeadZeros();
  362.  
  363. return result;
  364. }
  365. }
  366.  
  367.  
  368.  
  369. BigInteger BigInteger::operator%(const BigInteger &other) const {
  370.  
  371. bool result_sign = this->GetIsPositive() & other.GetIsPositive();
  372. BigInteger other_positive = {other.GetVectorOfDigits(), true};
  373. BigInteger this_positive = {this->GetVectorOfDigits(), true};
  374.  
  375.  
  376. std::vector<int> result_vector;
  377.  
  378. if (other_positive > this_positive) {
  379. result_vector.push_back(0);
  380. return {result_vector, true};
  381.  
  382. } else if (other_positive == this_positive) {
  383. result_vector.push_back(1);
  384. return {result_vector, result_sign};
  385.  
  386. } else {
  387.  
  388. size_t n = this->GetNumberOfDigits();
  389. result_vector.resize(n); // число разрядов в частном не больше чем в делимом
  390. std::vector<int> this_vector = this->GetVectorOfDigits();
  391. BigInteger current_value;
  392.  
  393. for (int i = n - 1; i >= 0; i--) {
  394.  
  395. current_value.MultiplyOnBase();
  396. current_value.vector_of_digits[0] = this_vector[i];
  397.  
  398. // подбираем максимальное число x, такое что b * x <= curValue
  399. for (int l = 0; l <= BASE; ++l) {
  400.  
  401. BigInteger attempt({l}, true);
  402. BigInteger cur = other_positive * attempt;
  403.  
  404. if (cur > current_value) {
  405. result_vector[i] = l - 1;
  406. current_value = current_value - other_positive * BigInteger({l-1}, true);
  407. current_value.DeleteLeadZeros();
  408. break;
  409. }
  410. }
  411. }
  412. current_value.SetIsPositive( result_sign );
  413. return current_value;
  414. }
  415. }
  416.  
  417.  
  418.  
  419. void BigInteger::operator+=(const BigInteger &other) {
  420. *this = (*this + other);
  421. }
  422.  
  423.  
  424.  
  425. void BigInteger::operator-=(const BigInteger &other) {
  426. *this = (*this - other);
  427. }
  428.  
  429. void BigInteger::operator*=(const BigInteger &other) {
  430. *this = (*this * other);
  431. }
  432.  
  433.  
  434.  
  435. void BigInteger::operator/=(const BigInteger &other) {
  436. *this = (*this / other);
  437. }
  438.  
  439.  
  440.  
  441.  
  442. bool BigInteger::operator==(const BigInteger &other) const {
  443. size_t n = this->GetNumberOfDigits();
  444. if ( n != other.GetNumberOfDigits() ) {
  445. return false;
  446. } else {
  447. if ( this->GetIsPositive() != other.GetIsPositive() ) {
  448. return false;
  449. } else {
  450. auto this_vector = this->GetVectorOfDigits();
  451. auto other_vector = other.GetVectorOfDigits();
  452. for (size_t i = 0; i < n; ++i) {
  453. if (this_vector[i] != other_vector[i]) { // there isn't matter where we are starting
  454. return false;
  455. }
  456. }
  457. return true;
  458. }
  459. }
  460. }
  461.  
  462.  
  463.  
  464. void BigInteger::Print() const {
  465. std::vector<int> vector = GetVectorOfDigits();
  466. for (int i = vector.size() - 1; i >= 0; --i) {
  467. std::cout<<vector[i];
  468. }
  469. std::cout<<'\n';
  470. }
  471.  
  472.  
  473.  
  474. size_t BigInteger::GetNumberOfDigits() const {
  475. return vector_of_digits.size();
  476. }
  477.  
  478. bool BigInteger::operator!=(const BigInteger &other) const {
  479. return !( *this == other );
  480. }
  481.  
  482. bool BigInteger::operator<=(const BigInteger &other) const {
  483. bool is_equal = ( *this == other );
  484. bool is_less = (*this < other);
  485. return is_equal || is_less;
  486. }
  487.  
  488.  
  489.  
  490. bool BigInteger::operator>=(const BigInteger &other) const {
  491. bool is_equal = ( *this == other );
  492. bool is_more = (*this > other);
  493. return is_equal || is_more;
  494. }
  495.  
  496.  
  497.  
  498. bool BigInteger::CompareByAbs(const BigInteger &other) const { // is this < other by abs?
  499. size_t n = this->GetNumberOfDigits();
  500. size_t m = other.GetNumberOfDigits();
  501.  
  502. if ( n < m ) {
  503. return true;
  504. } else if ( m == n ) {
  505.  
  506. auto this_vector = this->GetVectorOfDigits();
  507. auto other_vector = other.GetVectorOfDigits();
  508. for (size_t i = n - 1; i >= 0; --i) { // start from the end
  509. if (this_vector[i] < other_vector[i]) {
  510. return true;
  511. } else if (this_vector[i] > other_vector[i]) {
  512. return false;
  513. }
  514. }
  515. return false;
  516. } else {
  517. return false;
  518. }
  519. }
  520.  
  521. bool BigInteger::operator<(const BigInteger &other) const {
  522. bool is_less = false;
  523. // this - negative , other - positive
  524. if ( !this->GetIsPositive() && other.GetIsPositive() ) {
  525. is_less = true;
  526.  
  527. // this - positive , other - negative
  528. } else if ( this->GetIsPositive() && !other.GetIsPositive() ) {
  529. is_less = false;
  530.  
  531. // this & other have similar sign
  532. } else {
  533. // this & other negative
  534. if ( !this->GetIsPositive() && !other.GetIsPositive() ) {
  535. is_less = !(this->CompareByAbs(other));
  536. }
  537. // this & other positive
  538. if ( this->GetIsPositive() && other.GetIsPositive() ){
  539. is_less = this->CompareByAbs(other);
  540. }
  541. }
  542. return is_less && (*this != other);
  543. }
  544.  
  545.  
  546.  
  547. bool BigInteger::operator>(const BigInteger &other) const {
  548. return (!(*this < other)) && (*this != other);
  549. }
  550.  
  551.  
  552. std::ostream& operator<<(std::ostream &stream, const BigInteger& big_integer) {
  553.  
  554. std::vector<int> vector_of_digits = big_integer.GetVectorOfDigits();
  555. if ( !big_integer.is_positive ) {
  556. stream << '-';
  557. }
  558. for (int i = big_integer.GetNumberOfDigits() - 1; i >= 0; --i) {
  559. stream << vector_of_digits[i];
  560. }
  561. return stream;
  562. }
  563.  
  564.  
  565. std::istream& operator>>(std::istream &stream, BigInteger& big_integer) {
  566.  
  567. std::string str;
  568.  
  569. stream.setf(std::ios::skipws);
  570.  
  571. stream >> str;
  572.  
  573. int first_position_of_number = 0;
  574. if (str[0] == '-') {
  575. big_integer.is_positive = false;
  576. first_position_of_number = 1;
  577. if ( str.size() == 1 ) {
  578. std::string rest_of_str;
  579. stream >> rest_of_str;
  580. str.append(rest_of_str);
  581. }
  582. } else {
  583. big_integer.is_positive = true;
  584. }
  585.  
  586. for (int i = str.size() - 1; i >= first_position_of_number; --i) {
  587. std::string digit = {str[i]};
  588. big_integer.vector_of_digits.push_back(std::stoi(digit,nullptr,BASE));
  589. }
  590. return stream;
  591. }
  592.  
  593.  
  594.  
  595. BigInteger::operator int() {
  596.  
  597. int int_value = 0;
  598.  
  599. unsigned long long charge = 1;
  600. for (auto digit : this->GetVectorOfDigits()) {
  601. int_value += digit*charge;
  602. charge *= BASE;
  603. }
  604.  
  605. return int_value;
  606. }
  607.  
  608.  
  609.  
  610. BigInteger::operator bool() {
  611. for (auto digit : this->GetVectorOfDigits()) {
  612. if ( digit != 0 ) {
  613. return true;
  614. }
  615. }
  616. return false;
  617. }
  618.  
  619.  
  620. void BigInteger::SetIsPositive(bool sign) {
  621. this->is_positive = sign;
  622. }
  623.  
  624.  
  625.  
  626. std::string BigInteger::toString() {
  627. std::string string_number;
  628. for (int i = GetNumberOfDigits() - 1; i >= 0; --i) {
  629. std::string digit = std::to_string(vector_of_digits[i]);
  630. string_number.append(digit);
  631. }
  632. return string_number;
  633. }
  634.  
  635. #endif //FIVT_4_BIGINTEGER_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement