Advertisement
blufzzz

Fivt_4/task-A/06.12.2017 (check \)

Dec 5th, 2017
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.75 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4.  
  5. const int BASE = 10;
  6.  
  7. class BigInteger {
  8. public:
  9.     BigInteger(const std::vector<int>& _numbers, bool _is_positive);
  10.     void Print() const;
  11.     bool GetIsPositive() const;
  12.     size_t GetNumberOfDigits() const;
  13.     std::vector<int> GetVectorOfNumbers () const;
  14.     void SetIsPositive();
  15.     void MultiplyOnBase();
  16.     void DeleteLeadZeros();
  17.  
  18.     BigInteger operator + (const BigInteger& other) const;
  19.     BigInteger operator - (const BigInteger& other) const;
  20.     BigInteger operator - ();
  21.     BigInteger operator * (const BigInteger& other) const;
  22.     BigInteger operator / (const BigInteger& other) const;
  23.     BigInteger operator % (const BigInteger& other) const;
  24.  
  25.     void operator += (const BigInteger& other);
  26.     void operator -= (const BigInteger& other);
  27.     void operator *= (const BigInteger& other);
  28.     void operator /= (const BigInteger& other);
  29.  
  30.     BigInteger operator++() const;              // prefix-form
  31.     BigInteger operator++(int notused) const; // postfix-form
  32.     BigInteger operator--() const;              // prefix-form
  33.     BigInteger operator--(int notused) const; // postfix-form
  34.  
  35.     bool operator==(const BigInteger& other) const;
  36.     bool operator!=(const BigInteger& other) const;
  37.     bool operator<=(const BigInteger& other) const;
  38.     bool operator>=(const BigInteger& other) const;
  39.     bool operator<(const BigInteger& other) const;
  40.     bool operator>(const BigInteger& other) const;
  41.  
  42.     std::string toString();
  43. private:
  44.     std::vector<int> vector_of_numbers ;
  45.     bool is_positive;
  46.     bool CompareByAbs(const BigInteger& other) const;
  47. };
  48.  
  49.  
  50.  
  51. BigInteger::BigInteger(const std::vector<int>& _numbers, bool _is_positive) {
  52.     vector_of_numbers = _numbers;
  53.     is_positive = _is_positive;
  54. }
  55.  
  56.  
  57.  
  58. std::vector<int> BigInteger::GetVectorOfNumbers() const {
  59.     return vector_of_numbers;
  60. }
  61.  
  62.  
  63.  
  64. bool BigInteger::GetIsPositive() const {
  65.     return is_positive;
  66. }
  67.  
  68.  
  69.  
  70. BigInteger BigInteger::operator+(const BigInteger &other) const {
  71.  
  72.         // this is positive, other is negative
  73.     if (this->GetIsPositive() && !other.GetIsPositive()) {
  74.         BigInteger other_copy = other;                                      // MEMORY!
  75.         other_copy.SetIsPositive();
  76.         return (*this - other_copy);
  77.  
  78.         // this is negative, other is positive
  79.     } else if (!this->GetIsPositive() && other.GetIsPositive()) {
  80.         BigInteger this_copy = *this;                                       // MEMORY!
  81.         this_copy.SetIsPositive();
  82.         return (other - this_copy);
  83.  
  84.         // this & other are negative
  85.     } else if (!this->GetIsPositive() && !other.GetIsPositive()) {
  86.         BigInteger this_copy = *this;                                       // MEMORY!
  87.         this_copy.SetIsPositive();
  88.         BigInteger other_copy = other;                                      // MEMORY!
  89.         other_copy.SetIsPositive();
  90.         return -(this_copy + other_copy);
  91.  
  92.         // both operands are positive
  93.     } else {
  94.  
  95.         auto other_vector_of_numbers = other.GetVectorOfNumbers();
  96.         std::vector<int> result;
  97.         size_t n = vector_of_numbers.size();
  98.         size_t m = other_vector_of_numbers.size();
  99.  
  100.         int to_next_charge = 0;
  101.         for (size_t i = 0; i < n || i < m; ++i) {
  102.             int rest = 0;
  103.             int number = 0;
  104.  
  105.             number = ((i < m)? other_vector_of_numbers[i]:0) + ((i < n)? vector_of_numbers[i]:0) + to_next_charge;
  106.             rest = number%BASE;
  107.             if ( number >= BASE) {
  108.                 to_next_charge = 1;
  109.                 number = rest;
  110.             } else {
  111.                 to_next_charge = 0;
  112.             }
  113.  
  114.             result.push_back(number);
  115.         }
  116.  
  117.         if (to_next_charge != 0) {
  118.             result.push_back(to_next_charge);
  119.         }
  120.  
  121.         return {result, true};
  122.     }
  123. }
  124.  
  125.  
  126.  
  127. BigInteger BigInteger::operator-(const BigInteger &other) const {
  128.  
  129.     // this is positive, other is negative
  130.     if (this->GetIsPositive() && !other.GetIsPositive()) {
  131.         BigInteger other_copy = other;                                      // (+a) - (-b)
  132.         other_copy.SetIsPositive();
  133.         return (*this + other_copy);
  134.  
  135.         // this is negative, other is positive
  136.     } else if (!this->GetIsPositive() && other.GetIsPositive()) {           // (-a) - (+b)
  137.         BigInteger this_copy = *this;                                       // MEMORY!
  138.         this_copy.SetIsPositive();
  139.         BigInteger other_copy = other;                                      // MEMORY!
  140.         other_copy.SetIsPositive();
  141.         return -(this_copy + other_copy);                                   // -((+a) + (+b))
  142.  
  143.         // this & other are negative
  144.     } else if (!this->GetIsPositive() && !other.GetIsPositive()) {          //(-a) - (-b)
  145.         BigInteger this_copy = *this;                                       // MEMORY!
  146.         this_copy.SetIsPositive();
  147.         BigInteger other_copy = other;                                      // MEMORY!
  148.         other_copy.SetIsPositive();
  149.         return (other_copy - this_copy);
  150.  
  151.         // both operands are positive
  152.     } else {                                                                //(+a) - (+b)
  153.         std::vector<int> result;
  154.         // из большего - меньшее
  155.         if ( *this > other ) {
  156.  
  157.             auto other_vector_of_numbers = other.GetVectorOfNumbers();
  158.  
  159.             size_t n = vector_of_numbers.size();
  160.             size_t m = other_vector_of_numbers.size();
  161.  
  162.             int to_next_charge = 0;
  163.             int number = 0;
  164.  
  165.             for (size_t i = 0; i < n || i < m; ++i) {
  166.                 number = vector_of_numbers[i] - ((i < m)? other_vector_of_numbers[i]:0) - to_next_charge;
  167.                 if (number < 0) {
  168.                     result.push_back(number + BASE);
  169.                     to_next_charge = 1;
  170.                 } else {
  171.                     result.push_back(number);
  172.                     to_next_charge = 0;
  173.                 }
  174.             }
  175.  
  176.             // убираем нули в конце
  177.             while (result.back() == 0) {
  178.                 result.pop_back();
  179.             }
  180.  
  181.             return {result, true};
  182.  
  183.             // сводим к вычитанию из большего меньшее
  184.         } else if (*this == other) {
  185.             result.push_back(0);
  186.             return {result, true};
  187.         } else {
  188.             return -(other - *this);
  189.         }
  190.     }
  191. }
  192.  
  193.  
  194.  
  195. BigInteger BigInteger::operator-() {
  196.     this->is_positive = false;
  197.     return *this;
  198. }
  199.  
  200.  
  201.  
  202. BigInteger BigInteger::operator*(const BigInteger &other) const {
  203.  
  204.     size_t n = this->GetNumberOfDigits();
  205.     size_t m = other.GetNumberOfDigits();
  206.  
  207.     // умножение длинного на короткое
  208.     if ( n >= m ) {
  209.  
  210.         std::vector<int> this_vector = this->GetVectorOfNumbers();
  211.         std::vector<int> other_vector = other.GetVectorOfNumbers();
  212.  
  213.         bool result_sign = this->GetIsPositive() & other.GetIsPositive();
  214.  
  215.         std::vector<BigInteger> parts;
  216.         for (int j = 0; j < m; ++j) { // идем по короткому
  217.             int to_next_charge = 0;
  218.             std::vector<int> new_part(n + j);
  219.             for (int i = 0; i < n; ++i) { // по длинному
  220.  
  221.                 int value = (other_vector[j] * this_vector[i]) + to_next_charge;
  222.                 int rest = value % BASE;
  223.  
  224.                 if ( rest < value ) { //число больше 10
  225.                     to_next_charge = (value - rest)/BASE;
  226.                 } else {
  227.                     to_next_charge = 0;
  228.                 }
  229.                 new_part[i + j] = rest;
  230.  
  231.             }
  232.  
  233.             if ( to_next_charge > 0 ) {
  234.                 new_part.push_back(to_next_charge);
  235.             }
  236.  
  237.             parts.push_back({new_part,true});
  238.         }
  239.  
  240.         BigInteger result = parts[0];
  241.         for(int i = 1; i < parts.size(); ++i) {
  242.             result += parts[i];
  243.         }
  244.  
  245.         result.DeleteLeadZeros();
  246.  
  247.         return result;
  248.  
  249.     } else {
  250.         return (other * (*this));
  251.     }
  252.  
  253. }
  254.  
  255.  
  256. void BigInteger::MultiplyOnBase() {
  257.     vector_of_numbers.insert(vector_of_numbers.begin(),0);
  258. }
  259.  
  260.  
  261.  
  262. void BigInteger::DeleteLeadZeros() {
  263.     while (vector_of_numbers.back() == 0) {
  264.         vector_of_numbers.pop_back();
  265.     }
  266. }
  267.  
  268.  
  269. BigInteger BigInteger::operator/(const BigInteger &other) const {
  270.     bool result_sign = this->GetIsPositive() & other.GetIsPositive();
  271.     std::vector<int> result_vector;
  272.  
  273.     if (other > *this) {
  274.         result_vector.push_back(0);
  275.         return {result_vector, result_sign};
  276.  
  277.     } else if (other == *this) {
  278.         result_vector.push_back(1);
  279.         return {result_vector, result_sign};
  280.  
  281.     } else { //this > other     // what if this == {0}
  282.  
  283.         size_t n = this->GetNumberOfDigits();
  284.         result_vector.resize(n);    // число разрядов в частном не больше чем в делимом
  285.         std::vector<int> this_vector = this->GetVectorOfNumbers();
  286.         BigInteger curent_value({}, true);
  287.  
  288.         for (int i = n - 1; i >= 0; i--) {
  289.  
  290.             curent_value.MultiplyOnBase();
  291.             curent_value.vector_of_numbers[0] = this_vector[i]; //?? private
  292.  
  293.             // подбираем максимальное число x, такое что other * x <= curent_value
  294.             for (size_t l = 0; l <= BASE; ++l) {
  295.                 BigInteger proba({l}, true);
  296.                 BigInteger cur = other * proba;
  297.                 if (cur > curent_value) {
  298.                     result_vector[i] = l - 1;
  299.                     curent_value = curent_value - other * BigInteger({l - 1}, true);
  300.                     curent_value.DeleteLeadZeros();
  301.                     break;
  302.                 }
  303.             }
  304.         }
  305.  
  306.         BigInteger result {result_vector, result_sign};
  307.         result.DeleteLeadZeros();
  308.  
  309.         return result;
  310.  
  311.     }
  312. }
  313.  
  314.  
  315.  
  316. BigInteger BigInteger::operator%(const BigInteger &other) const {
  317.  
  318. }
  319.  
  320.  
  321.  
  322. void BigInteger::operator+=(const BigInteger &other) {
  323.     *this = (*this + other);
  324. }
  325.  
  326.  
  327.  
  328. void BigInteger::operator-=(const BigInteger &other) {
  329.     *this = (*this - other);
  330. }
  331.  
  332. void BigInteger::operator*=(const BigInteger &other) {
  333.     *this = (*this * other);
  334. }
  335.  
  336.  
  337.  
  338. void BigInteger::operator/=(const BigInteger &other) {
  339.     *this = (*this / other);
  340. }
  341.  
  342.  
  343.  
  344.  
  345. bool BigInteger::operator==(const BigInteger &other) const {
  346.     size_t  n = this->GetNumberOfDigits();
  347.     if ( n != other.GetNumberOfDigits() ) {
  348.         return  false;
  349.     } else {
  350.         if ( this->GetIsPositive() != other.GetIsPositive() ) {
  351.             return  false;
  352.         } else {
  353.             auto this_vector = this->GetVectorOfNumbers();
  354.             auto other_vector = other.GetVectorOfNumbers();
  355.             for (size_t i = 0; i < n; ++i) {
  356.                 if (this_vector[i] != other_vector[i]) { // there isn't matter where we are starting
  357.                     return false;
  358.                 }
  359.             }
  360.             return true;
  361.         }
  362.     }
  363. }
  364.  
  365.  
  366.  
  367. void BigInteger::Print() const {
  368.     std::vector<int> vector = GetVectorOfNumbers();
  369.     for (int i = vector.size() - 1; i >= 0; --i) {
  370.         std::cout<<vector[i];
  371.     }
  372.     std::cout<<'\n';
  373. }
  374.  
  375.  
  376.  
  377. size_t BigInteger::GetNumberOfDigits() const {
  378.     return vector_of_numbers.size();
  379. }
  380.  
  381. bool BigInteger::operator!=(const BigInteger &other) const {
  382.     return !( *this == other );
  383. }
  384.  
  385. bool BigInteger::operator<=(const BigInteger &other) const {
  386.     bool is_equal = ( *this == other );
  387.     bool is_less = (*this < other);
  388.     return is_equal || is_less;
  389. }
  390.  
  391.  
  392.  
  393. bool BigInteger::operator>=(const BigInteger &other) const {
  394.     bool is_equal = ( *this == other );
  395.     bool is_more = (*this > other);
  396.     return is_equal || is_more;
  397. }
  398.  
  399.  
  400.  
  401. bool BigInteger::CompareByAbs(const BigInteger &other) const { // is this < other by abs?
  402.     size_t  n = this->GetNumberOfDigits();
  403.     size_t m = other.GetNumberOfDigits();
  404.  
  405.     if ( n < m ) {
  406.         return  true;
  407.     } else if ( m == n ) {
  408.  
  409.         auto this_vector = this->GetVectorOfNumbers();
  410.         auto other_vector = other.GetVectorOfNumbers();
  411.         for (size_t i = n - 1; i >= 0; --i) {  // start from the end
  412.             if (this_vector[i] < other_vector[i]) {
  413.                 return true;
  414.             } else if (this_vector[i] > other_vector[i]) {
  415.                 return  false;
  416.             }
  417.         }
  418.         return  false;
  419.     } else {
  420.         return false;
  421.     }
  422. }
  423.  
  424. bool BigInteger::operator<(const BigInteger &other) const {
  425.     bool is_less = false;
  426.     // this - negative , other - positive
  427.     if ( !this->GetIsPositive() && other.GetIsPositive() ) {
  428.         is_less = true;
  429.  
  430.         // this - positive , other - negative
  431.     } else if ( this->GetIsPositive() && !other.GetIsPositive() ) {
  432.         is_less = false;
  433.  
  434.         // this & other have similar sign
  435.     } else {
  436.         // this & other negative
  437.         if ( !this->GetIsPositive() && !other.GetIsPositive() ) {
  438.             is_less = !(this->CompareByAbs(other));
  439.         }
  440.         // this & other positive
  441.         if ( this->GetIsPositive() && other.GetIsPositive() ){
  442.             is_less = this->CompareByAbs(other);
  443.         }
  444.     }
  445.     return  is_less && (*this != other);
  446. }
  447.  
  448.  
  449.  
  450. bool BigInteger::operator>(const BigInteger &other) const {
  451.     return (!(*this < other)) && (*this != other);
  452. }
  453.  
  454. void BigInteger::SetIsPositive() {
  455.     this->is_positive = true;
  456. }
  457.  
  458.  
  459.  
  460.  
  461. int main() {
  462.  
  463.     BigInteger a({6,5,0,1},true);
  464.     BigInteger b({2,2},true);
  465.  
  466. //  std::cout<<(a != b)<<std::endl;
  467. //  std::cout<<(a == b)<<std::endl;
  468. //  std::cout<<(a < b)<<std::endl;
  469. //  std::cout<<(a > b)<<std::endl;
  470. //  std::cout<<(a <= b)<<std::endl;
  471. //  std::cout<<(a >= b)<<std::endl;
  472.  
  473.     (a / b).Print();
  474.     std::cout<<(a / b).GetIsPositive();
  475.  
  476.     return  0;
  477. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement