Задать вопрос
@Sunter

Как переделать код под ООП?

#include <iostream>
#include <string>
using namespace std;
// операции над числами
int mod(int a,int b) // %
{
    if (a>= b) {
        return mod(a-b,b);
    } else {
        return a;
    }
}

int divide(int a, int b) // /
{
    if (a == b){
      return 1;
    }
    else
    {
        int quot=0;
        for(int i = a-b;i>=0;i-=b)
        {
           quot++;
        }
        return quot;
    }
}

 int multiply( int a, int b) // *
{
    int result = 0;
    while (b != 0) {
      if (b & 0x1 == 0x1)
        result += a;

      b >>= 1;
      a <<= 1;
    }
    return result;
}
// ----------------------------
//операции над строками
string leadZero(string str) // удаление ведущих нулей
{
    int count = 0;
    while (str[count] == '0' && str.length() - count > 1)
        count++;
    return str.substr(count);
}
string reverseStr(string str) // переворот строки
{
    char ch;
    for (int index = 0, len = str.length(); index < divide(len,2); index++) {
        ch = str[index];
        str[index] = str[len-1-index];
        str[len-1-index] = ch;
    }
    return str;
}

bool les(string st1,string st2) // operator <
{
    size_t len1 = st1.length();
    size_t len2 = st2.length();
    if (len1 != len2) return (len1 < len2);
    long int i = 0;

        // ищем разряд, в котором значения отличаются
    while (i < len1 && st1[i] == st2[i])
    {
        i++;
    }

        // если разряд найден, то меньше число с меньшей цифрой для положительных и с большей цифрой для отрицательных, иначе числа равны
    return (i < len1) && ((st1[i] < st2[i]) );
}

bool ge(string st1,string st2) // operator  >=
{
    size_t len1 = st1.length();
    size_t len2 = st2.length();
    if (len1 != len2) return (len1 > len2);
    long int i = 0;

        // ищем разряд, в котором значения отличаются
    while (i < len1 && st1[i] == st2[i])
    {
        i++;
    }

    return (i <= len1) && ((st1[i] >= st2[i]) );
}



string SUM(string st1, string st2) // сложение строк
{

    st1 = "0" + st1;
    int borrow = 0;
    int i = st1.length() - 1;
    int j = st2.length() - 1;
    string result = "";

    while (i >= 0 || j >= 0) {
        int x = (i >= 0) ? (st1[i--] - '0') : 0;
        int y = (j >= 0) ? (st2[j--] - '0') : 0;
        int diff = (x + borrow) + y;
        borrow = (diff >= 10) ? 1 : 0;
        if (diff >= 10)
            diff -= 10;
        result += diff + '0';
    }
    return leadZero(reverseStr(result));
}

string SUB(string st1, string st2) { // вычитание строк
    int borrow = 0;
    int i = st1.length() - 1;
    int j = st2.length() - 1;
    string result = "";

    while (i >= 0 || j >= 0) {
        int x = (i >= 0) ? (st1[i--] - '0') : 0;
        int y = (j >= 0) ? (st2[j--] - '0') : 0;
        int diff = (x - borrow) - y;
        borrow = (diff < 0) ? 1 : 0;
        if (diff < 0)
            diff += 10;
        result += diff + '0';
    }



    result = reverseStr(result);

    return leadZero(result);
}

string MULTI(string st1,string st2) {
    int borrow = 0;
    int i = st1.length() - 1;
    int j = st2.length() - 1;
    st1= std::string(st1.length()+st2.length()+1,'0') + st1;
    string result = "";
    string resultM = "";
    while (j >= 0) {

        resultM = std::string(st2.length()-1-j,'0');
        int y = st2[j--]-'0';
        int i = st1.length() - 1;
        while (i >= 0) {
            int x = (i >= 0) ? (st1[i--] - '0') : 0;
            int diff = multiply(x ,y)+borrow;
            borrow = (diff >= 10) ? divide(diff,10) : 0;
            if (diff >= 10)
                diff = mod(diff,10);
            resultM += diff + '0';
        }
        result = SUM(result,reverseStr(resultM));
    }
    return leadZero(result);
}


string  powerOfTwo(long int  e) // 2^e
{
    string res = "1";
    for (int i = 0;i < e; i++) {
        res = MULTI(res,"2");
    }
    return res;
}

string divide( string a, string b)
{
    string res;
    if (les(a,b)) return "0";
    long int c = 0;
    //!(a>=2^c*b && a < 2^(c+1)*b)
    while(!(ge(a,MULTI(b,powerOfTwo(c))) && les(a,MULTI(b,powerOfTwo(c+1)))))
    {
        c++;
    }
    res = SUM(divide(SUB(a,MULTI(b,powerOfTwo(c))),b),powerOfTwo(c));
    //divide_unsigned(a-2^c*b,b)+2^c

    return res;
}

int main()
{
    string a = "11111111111111111111111111111111";
    string b = "45";
    cout<<divide(a,b)<<endl;
    return 0;
}
  • Вопрос задан
  • 252 просмотра
Подписаться 1 Простой 1 комментарий
Решение пользователя code_panik К ответам на вопрос (3)
@code_panik
Сначала замечу, что нет никакого смысла переписывать код в стиле ООП, потому что класс, назовем его Calculator, не имеет состояния, не хранит данных, состоит только из функций. То есть весь код будет выглядеть как раньше, но придется приписывать в начало операций имя объекта класса типа Calculator, напр. calculator.divide(1, 2);. Достаточно собрать эти функции в нашем пространстве имен my_math, например,
namespace my_math {
bool operator<(const std::string& st1, const std::string& st2) {
    size_t len1 = st1.length();
    size_t len2 = st2.length();
    if (len1 != len2) return (len1 < len2);
    long int i = 0;
        // ищем разряд, в котором значения отличаются
    while (i < len1 && st1[i] == st2[i])
    {
        i++;
    }
        // если разряд найден, то меньше число с меньшей цифрой для положительных и с большей цифрой для отрицательных, иначе числа равны
    return (i < len1) && ((st1[i] < st2[i]) );
}
bool les(int lhs, int rhs) {
    return lhs <= rhs;
}
}

int main() {
    using my_math::operator<; // иначе cout << my_math::operator<(s1, s2) << endl;
    std::string s1 = "1", s2 = "2";
    cout << (s1 < s2) << endl;

    int a = 1, b = 2;
    cout << (my_math::les(a, b)) << endl;
    return 0;
}

Для ООП можно воспользоваться примером https://godbolt.org/z/rEPzdKe4j. В нем определены два файла: calculator.h и calculator.cpp с объявлением класса и реализацией соответственно.
Замечу, что в реализациях бинарных операций не следует передавать string по значению, чтобы избежать лишних копирований. Если заменить тип аргумента std::string на ссылочный const std::string&, придется поправить код, чтобы он не изменял значения аргументов.
Ответ написан
Комментировать