Задать вопрос
@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;
}
  • Вопрос задан
  • 244 просмотра
Подписаться 1 Простой 1 комментарий
Решения вопроса 2
@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&, придется поправить код, чтобы он не изменял значения аргументов.
Ответ написан
Комментировать
@vanyamba-electronics
По Вашей просьбе оформил в ООП.
С такими алгоритмами недолго и программистом стать.
https://onlinegdb.com/q6b6nwNdX
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
mayton2019
@mayton2019
Bigdata Engineer
Программирование в ООП предполагает что мир состоит из "объектов".
Например твоя программ (процесс) калькулятор это уже объект. Даже не имея декларации
она уже является объектом с точки зрения ОС.

Но если твой преподаватель - такой душный, то сделай

class Calculator {
   ...
}

Можно сделать объектом число и операцию над ним (унарная или бинарная) но это уже немотивированное
(или слабо мотивированное) действие. Теоретики ООП всегда пишут что введение объекта должно иметь смысл. Иначе так можно
дойти до абсурда и объявлять объектом любую чепуху, что только усложнит написание кода
и создаст бюрократию на пустом месте.

Поясни это преподавателю если он будет сильно настаивать на том что мало объектов.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы