Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Spiderman5
31 / 31 / 14
Регистрация: 07.04.2014
Сообщений: 219
#1

Переделать строчный калькулятор через ООП - C++

24.07.2014, 20:09. Просмотров 762. Ответов 6
Метки нет (Все метки)

Друзья, имею отличный строчный калькулятор, сделанный через процедурное программирование.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#define _CRT_SECURE_NO_WARNINGS
 
#include <iostream>
#include <conio.h>
//#include <string>
using namespace std;
 
#define Esc 27
 
double Do_Polynom(const char* polynom, int first, int last);
 
// не учитывает пробелы, которые пользователь может ввести
void Space(char* string)
{
    int i = 0;                          // индекс места в строке "куда копировать"
    int j = 0;                          // индекс места в строке "откуда копировать"
 
    /*while (   (  *(string + i) = *(string + j++)  ) != '\0'   ) // цикл, пока очередной символ не '\0'
    {
        if (*(string + i) != ' ')  // увеличиваем i, если символ не пробел
            i++;
    }
    return;*/
 
    while ((string[i] = string[j++]) != '\0')
    {
        if (string[i] != ' ')
            i++;
    }
    return;
}
 
//переводит входящую строку в число с учетом скобок и десятичной точки
double Do_Number(const char* number, int first, int last)
{
    if (number[first] == '(')
        return Do_Polynom(number, first + 1, last - 1);
 
    int length = last - first + 1;
 
    if (!length) // если длина = 0
        return 0;
 
    char* temp = new char[length + 1];
 
    for (int i = 0; i < length; i++)
        temp[i] = number[i + first];
 
    temp[length] = '\0';
 
    double result = atof(temp);
 
    delete[] temp;
 
    return result;
}
 
//вычисляет степень - принимает строку и индексы символов, ограничивающие степень
double Do_Power(const char* power, int first, int last)
{
    int i = last;
 
    for (int count = 0; i >= first; i--)
    {
        if (power[i] == ')')
            count++;
 
        else if (power[i] == '(')
            count--;
 
        if (!count && power[i] == '^')
            break;
    }
 
    if (i < first)
        return Do_Number(power, first, last);
 
    double base = Do_Power(power, first, i - 1);
    double exponent = Do_Number(power, i + 1, last);
 
    return pow(base, exponent); // функция pow вычисляет base, возведённое в степень exponent
}
 
//вычисляет одночлен - принимает строку и индексы символов, ограничивающие нужный одночлен
double Do_Monom(const char* monom, int first, int last)
{
    int i = last;
 
    for (int count = 0; i >= first; i--)
    {
        if (monom[i] == ')')
            count++;
 
        else if (monom[i] == '(')
            count--;
 
        if (!count && (monom[i] == '*' || monom[i] == '/'))
            break;
    }
 
    if (i < first)
        return Do_Power(monom, first, last);
 
    double right = Do_Monom(monom, first, i - 1);
    double left = Do_Power(monom, i + 1, last);
 
    if (monom[i] == '*')
        return right * left;
 
    if (!left)
        cout << "Division by zero is forbidden! Try again more carefully";
    return right / left;
}
 
//вычисляет многочлен - принимает строку и индексы символов, ограничивающие нужный многочлен
double Do_Polynom(const char* polynom, int first, int last)
{
    int i = last;
 
    for (int count = 0; i >= first; i--)
    {
        if (polynom[i] == ')')
            count++;
 
        else if (polynom[i] == '(')
            count--;
 
        if (!count && (polynom[i] == '+' || polynom[i] == '-'))
            break;
    }
 
    if (i < first)
        return Do_Monom(polynom, first, last);
 
    return Do_Polynom(polynom, first, i - 1) + ((polynom[i] == '+') ? 1 : -1) * Do_Monom(polynom, i + 1, last);
}
 
//вычисляет выражение, переданное строкой
double Execute(char* expression) // expression - выражение
{
    int length = strlen(expression);
 
    if (!length)
        return 0;
 
    int count = 0;
 
    for (int i = 0; i < length; i++)
    {
        if (expression[i] == '(') // скобка открылась
            count++;
 
        else if (expression[i] == ')') // скобка должна закрыться
            count--;
 
        else if (!(expression[i] == '.' || expression[i] == '+' || expression[i] == '-' ||
            expression[i] == '*' || expression[i] == '/' || expression[i] == ' ' || expression[i] == '^' || expression[i] >= '0' && expression[i] <= '9'))
        {
            cout << "Wrong symbol detected! Try again more carefully";
            return 0;
        }
    }
 
    if (count)
    {// если случилась лишняя скобка
        cout << "Wrong count of brackets!" << endl;
        cout << "Try again more carefully";
 
        return 0;
    }
    
    return Do_Polynom(expression, 0, length - 1);
}
 
void main()
{
    //cout << Execute("(3+5)*6.34-8+9^2/2") << endl;
    //cout << "3.5+2*5" << " = " << Execute("3.5+2*5") << endl;                              //  13.5
    //cout << "(3+2)*5" << " = " << Execute("(3+2)*5") << endl;                              //  25
    //cout << "(3+4*(5-2)-1)/2" << " = " << Execute("(3+4*(5-2)-1)/2") << endl;        //   7
    //cout << "(3+5)^2-60-2^3" << " = " << Execute("(3+5)^2-60-2^3") << endl;       //  -4
    
    setlocale(LC_ALL, "Russian");
    char s[80] = { 0 };
 
    while (true)
    {       
        cout << "Введите арифметическое выражение:" << endl;
        //cin.getline(s, 80);
        //cin.getline(s, sizeof s);
 
        gets(s);
        Space(s); // удаляем все пробелы из строки
        if (!s[0])
            return;
 
        cout << " = " << Execute(s) << endl;
        
        if (_getch() == Esc)
            exit(0);
    }
}
Я из этого кальукулятора делал класс, но запутался с конструкторами и другими вещами и не знаю, как реализовать.

Calculate.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#pragma once
 
#include <iostream>
using namespace std;
 
class Calculate
{
private:
    char str;
public:
    Calculate();
    Calculate(char _str) { str = _str; };
    //Calculate(const char* str);
    //~Calculate();
 
    /*const char* GetStr() const { return str; }
    void SetStr(const char* s);*/
 
    void Space(char* string); // не учитывает пробелы, которые пользователь может ввести
    
    double Do_Number(const char* number, int first, int last); // переводит входящую строку в число с учетом скобок и десятичной точки
 
    double Do_Power(const char* power, int first, int last); // вычисляет степень - принимает строку и индексы символов, ограничивающие степень
 
    double Do_Monom(const char* monom, int first, int last); // вычисляет одночлен - принимает строку и индексы символов, ограничивающие нужный одночлен
 
    double Do_Polynom(const char*, int first, int last); // вычисляет многочлен - принимает строку и индексы символовб ограничивающие нужный многочлен
 
    double Execute(const char* expression); // вычисляет выражение, переданное строкой
};
Calculate.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include "Calculate.h"
 
void Calculate::Space(char* string)
{
    int i = 0;                          // индекс места в строке "куда копировать"
    int j = 0;                          // индекс места в строке "откуда копировать"
 
    /*while (   (  *(string + i) = *(string + j++)  ) != '\0'   ) // цикл, пока очередной символ не '\0'
    {
    if (*(string + i) != ' ')  // увеличиваем i, если символ не пробел
    i++;
    }
    return;*/
 
    while ((string[i] = string[j++]) != '\0')
    {
        if (string[i] != ' ')
            i++;
    }
    return;
}
 
double Calculate::Do_Number(const char* number, int first, int last)
{
    if (number[first] == '(')
        return Do_Polynom(number, first + 1, last - 1);
 
    int length = last - first + 1;
 
    if (!length)
        return 0;
 
    char* temp = new char[length + 1];
 
    for (int i = 0; i < length; i++)
        temp[i] = number[i + first];
 
    temp[length] = '\0';
 
    double result = atof(temp);
 
    delete[] temp;
 
    return result;
}
 
double Calculate::Do_Power(const char* power, int first, int last)
{
    int i = last;
 
    for (int count = 0; i >= first; i--)
    {
        if (power[i] == ')')
            count++;
 
        else if (power[i] == '(')
            count--;
 
        if (!count && power[i] == '^')
            break;
    }
 
    if (i < first)
        return Do_Number(power, first, last);
 
    double base = Do_Power(power, first, i - 1);
    double exponent = Do_Number(power, i + 1, last);
 
    return pow(base, exponent);
}
 
double Calculate::Do_Monom(const char* monom, int first, int last)
{
    int i = last;
 
    for (int count = 0; i >= first; i--)
    {
        if (monom[i] == ')')
            count++;
 
        else if (monom[i] == '(')
            count--;
 
        if (!count && (monom[i] == '*' || monom[i] == '/'))
            break;
    }
 
    if (i < first)
        return Do_Power(monom, first, last);
 
    double right = Do_Monom(monom, first, i - 1);
    double left = Do_Power(monom, i + 1, last);
 
    if (monom[i] == '*')
        return right * left;
 
    if (!left)
        cout << "Division by zero is forbidden. Try again more carefully";
    return right / left;
}
 
double Calculate::Do_Polynom(const char* polynom, int first, int last)
{
    int i = last;
 
    for (int count = 0; i >= first; i--)
    {
        if (polynom[i] == ')')
            count++;
 
        else if (polynom[i] == '(')
            count--;
 
        if (!count && (polynom[i] == '+' || polynom[i] == '-'))
            break;
    }
 
    if (i < first)
        return Do_Monom(polynom, first, last);
 
    return Do_Polynom(polynom, first, i - 1) + ((polynom[i] == '+') ? 1 : -1) * Do_Monom(polynom, i + 1, last);
}
 
double Calculate::Execute(const char* expression)
{
    int length = strlen(expression);
 
    if (!length)
        return 0;
 
    int count = 0;
 
    for (int i = 0; i < length; i++)
    {
        if (expression[i] == '(')
            count++;
 
        else if (expression[i] == ')')
            count--;
 
        else if (!(expression[i] == '.' || expression[i] == '+' || expression[i] == '-' || expression[i] == '*' || expression[i] == '/'
            || expression[i] == '^' || expression[i] >= '0' && expression[i] <= '9'))
        {
            cout << "Wrong symbol detected ! Try again more carefully";
            return 0;
        }
    }
 
    if (count)
    {// если случилась лишняя скобка
        cout << "Wrong count of brackets!" << endl;
        cout << "Try again more carefully";
 
        return 0;
    }
 
    return Do_Polynom(expression, 0, length - 1);
}
Main.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "Calculate.h"
#include <conio.h>
 
void main()
{
    setlocale(LC_ALL, "Russian");
 
    Calculate s;
 
    cout << "Введите арифметическое выражение:" << endl;
    cin.getline(s, 80);
    
    //cout << s.Execute("2+3+7-9") << endl;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.07.2014, 20:09
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Переделать строчный калькулятор через ООП (C++):

ООП калькулятор - C++
Начал изучать ООП, задание сделать класс с названием Int, в котором будет спрашиваться, хотите ли вы ввести значения для i1, i2, если нет...

Переделать код в ООП - C++
Помогите переделать код в ООП #include &quot;stdafx.h&quot; #include &lt;stdlib.h&gt; #include&lt;iostream&gt; #include &lt;conio.h&gt; #include...

Переделать программу в ООП - C++
Здравствуйте, помогите пожалуйста переделать программу под ООП с применением класса. Все функции алгоритма должны быть его методами....

Переделать калькулятор - C++
Всем привет помогите сделать калькулятор в функции, как то вот так но мне выдаёт всякий бред. #include &lt;iostream&gt; #include...

Из консольного проекта с++ переделать в стиле ООП с интерфейсом на QT - C++
Добрый день! Делал на 1 заочном курсе курсовую работу по матрицам на с++ в консольном режиме, все работает. Однако сейчас,...

программа сделана через указатели, переделать через ссылки. - C++
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;iomanip&gt; #include &lt;cmath&gt; using namespace std; void calculation(double...

6
Komi
6 / 6 / 2
Регистрация: 10.08.2012
Сообщений: 82
25.07.2014, 08:39 #2
Очень длинная задача, сомневаюсь что кто-то за нее возьмется.
Советую задать более спецефический вопрос в новой теме.
0
SatanaXIII
Супер-модератор
Эксперт С++
5619 / 2654 / 247
Регистрация: 01.11.2011
Сообщений: 6,554
Завершенные тесты: 1
25.07.2014, 09:54 #3
Цитата Сообщение от Spiderman5 Посмотреть сообщение
и не знаю, как реализовать
Как реализовать что?

Какой-то кусок, вон, у вас есть. Прикручивайте к нему потихоньку все остальное. Какие-то конкретные вопросы будут возникать - спрашивайте.
0
Spiderman5
31 / 31 / 14
Регистрация: 07.04.2014
Сообщений: 219
25.07.2014, 16:47  [ТС] #4
Я не знаю, можно ли тут решить ее, не используя стек, вектор или список.
Если можно, то для начала мне непонятно, какие именно конструкторы мне нужны в данной задаче ?
0
SatanaXIII
Супер-модератор
Эксперт С++
5619 / 2654 / 247
Регистрация: 01.11.2011
Сообщений: 6,554
Завершенные тесты: 1
25.07.2014, 18:04 #5
Цитата Сообщение от Spiderman5 Посмотреть сообщение
не используя стек, вектор или список
Массив, строка, зачем.

Цитата Сообщение от Spiderman5 Посмотреть сообщение
мне непонятно, какие именно конструкторы мне нужны в данной задаче
Представьте себе объект калькулятора. Что можно создать такого, какую-то единицу чего-то, чем бы можно было оперировать?
0
Spiderman5
31 / 31 / 14
Регистрация: 07.04.2014
Сообщений: 219
25.07.2014, 20:25  [ТС] #6
Ну строку создать или массив строк наверное.
0
Памирыч
22.08.2014, 07:51     Переделать строчный калькулятор через ООП
  #7
 Комментарий модератора 
Закрыто
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.08.2014, 07:51
Привет! Вот еще темы с ответами:

ООП "Класс калькулятор - дата" - C++
Добрый день. Есть такая задачка: Разработать класс калькулятор(с формой) выполняющий операции например: 1) дата1-дата2 = количество...

Из ООП - динамическая структура через агрегацию - C++
Всем привет! Помогите реализовать динамическую структуру через агрегацию. есть абстрактный класс class iXml { public: ...

Основы ООП. Создание стека через класс - C++
Приветствую всех пользователей форума. Относительно недавно начал осваивать ООП. Было необходимо выполнить следующее задание : нужно...

Строчный массив - C++
Всем доброго времени суток. Никак не могу найти решение проблемы в ответах на вопросы других пользователей, поэтому решил создать свою...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
22.08.2014, 07:51
Закрытая тема Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru