Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
0 / 0 / 0
Регистрация: 05.04.2024
Сообщений: 31

Вычислить введенное арифметическое выражение

30.05.2024, 10:33. Показов 1121. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Написать программу, которая вычисляет значение выражения
N0 O1 N1 O2...Ok Nk, где Ni – целое число, Oi – один из двух знаков простейших
арифметических действий: сложение (+) и вычитание (–). Отдельной функцией обеспечить контроль корректного ввода: в строке должны быть заданы
только цифры и указанные знаки действий. Ниже представлен рекомендуемый
вид диалога во время работы программы.

Введите арифметическое выражение,
например, 45+5-3-125+2 (пробелы и другие знаки недопустимы)
354-457+74+2-37
Значение выражения 354-457+74+2-37 = -64
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
30.05.2024, 10:33
Ответы с готовыми решениями:

Вычислить выражение, введенное с клавиатуры
Начали изучать класс string, получил задание, с клавиатуры вводиться математическое выражение, например, вида - (2+3)*4+1, получить...

Вычислить выражение, введенное в строку
Помогите пожалуйста написать программу. Со строками вообще не имел дела. Друг попросил выручить. Заранее спасибо.

Вычислить арифметическое выражение
пожалуйста помогите : Дано натуральное число n. Вычислить

8
Лежебока
 Аватар для Donkix
328 / 244 / 95
Регистрация: 12.05.2021
Сообщений: 1,429
Записей в блоге: 2
30.05.2024, 10:47
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int n, x;
char ch;
int sum = 0;
std::cin >> n;
for(int i = 0; i < n; i++)
{
    std::cin >> x;
    std::cin >> ch;
    if(ch == "-")
        sum -= x;
    if(ch == "+")
        sum += x;
    else
    {
        std::cout << "Error input. Try again.";
        i--;
     }
}
+- похоже, диалог сможете и сами добавить
1
Модератор
Эксперт С++
 Аватар для zss
13773 / 10966 / 6491
Регистрация: 18.12.2011
Сообщений: 29,245
30.05.2024, 11:15
Лучший ответ Сообщение было отмечено vitvinki как решение

Решение

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
#include <iostream>
 
int main()
{
    int n;
    char ch;
    int sum = 0;
    std::cout<<"Enter expression:";
    std::cin >> sum;
    while(std::cin.get(ch))
    {
        switch(ch)
        {
        case '-':
            std::cin >> n;
            sum -= n;break;
        case '+':
            std::cin >> n;
            sum += n;break;
        case '\n':
            std::cout << "result="<<sum<<'\n';
            std::cout<<"Enter new expression:";
            sum=0;std::cin.putback('+');break;
        default:
            std::cout << "Error input\n";
            std::cin.get();return 1;
        }
    }
    std::cout << "Input fail\n";
    std::cin.clear();
    std::cin.get();
    return -1;
}
1
848 / 651 / 323
Регистрация: 24.02.2017
Сообщений: 2,297
30.05.2024, 12:43
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
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
 
int f(string &s){
    size_t i=0;
    getline(cin,s);
    while(s[i]){
        if(!isdigit(s[i]) && s[i]!='+' && s[i]!='-'){
            cout<<"incorrect expression";
            return 0;
        }
         i++;
    }
    return 1;
}
        
int main() {
    string s;
    stringstream t;
    int a,sum=0;
    
   f(s)==1 ? 1 : f(s);      
    t<<s;
    while(t>>a) sum+=a;
    cout<<sum;     
    return 0;
}
1
place status here
 Аватар для gunslinger
3190 / 2227 / 640
Регистрация: 20.07.2013
Сообщений: 6,023
31.05.2024, 19:15
Можно так сделать:
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
#include <iostream>
#include <string>
using namespace std;
 
string func (string str)
{
  int tmp = 0, result = 0, i, n = str.size(), op = 0;
  bool prev_op = true;
  string error = "error";
 
  if (!isdigit(str[0]) || !isdigit(str[n - 1]))
    return error;
 
  for (i = 0; i < n; i++)
  {
    if (!isdigit(str[i]) && str[i] != '+' && str[i] != '-')
      return error;
 
    if (isdigit(str[i]))
    {
      op = 0;
      tmp = tmp * 10 + (str[i] - '0');
    }
 
    if (str[i] == '+' || str[i] == '-')
    {
      if (op > 0)
        return error;
 
      result += prev_op ? tmp : -tmp;
 
      op = (str[i] == '+' ? 1 : 2);
      prev_op = (str[i] == '+');
      tmp = 0;
    }
  }
 
  result += prev_op ? tmp : -tmp;
  char *val;
  itoa(result, val, 10);
  return val;
}
 
int main()
{
  string str = "45+5-3-125+2";  // 354-457+74+2-37
  cout << str << " = " << func(str) << "\n\n";
 
  system("pause");
  return 0;
}
Code
1
45+5-3-125+2 = -76
Добавлено через 52 минуты
Подправил функцию:
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
string func (string str)
{
  int tmp = 0, result = 0, i, n = str.size();
  bool flag = false, op = true;
  string error = "error";
  if (!isdigit(str[0]) || !isdigit(str[n - 1]))
    return error;
 
  for (i = 0; i < n; i++)
  {
    if (!isdigit(str[i]) && str[i] != '+' && str[i] != '-')
      return error;
 
    if (isdigit(str[i]))
      flag = false, tmp = tmp * 10 + (str[i] - '0');
 
    if (str[i] == '+' || str[i] == '-')
    {
      if (flag)
        return error;
      result += (op ? tmp : -tmp);
      flag = true;
      op = (str[i] == '+');
      tmp = 0;
    }
  }
 
  result += (op ? tmp : -tmp);
  char val[100];
  itoa(result, val, 10);
  return val;
}
Кстати, билдер позволяет такое (без видимых проблем):
C++
29
30
31
32
  char *val = new char[n];
  itoa(result, val, 10);
  delete[] val;
  return val;
Это вообще законно - "удалять массив", а потом его использовать?
Типа память еще не занята чем-то другим или как это работает?
Либо мне просто повезло?
1
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
31.05.2024, 19:41
Цитата Сообщение от gunslinger Посмотреть сообщение
Это вообще законно - "удалять массив", а потом его использовать?
Законно, хоть в представленном случае и абсолютно бессмысленно.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13177 / 6813 / 1821
Регистрация: 18.10.2014
Сообщений: 17,238
31.05.2024, 21:09
Цитата Сообщение от vitvinki Посмотреть сообщение
в строке должны быть заданы только цифры и указанные знаки действий. ...(пробелы и другие знаки недопустимы)
Другими словами, вся постановка задачи предназначена лишь для того, чтобы сбить студента с толку. Вспоминаем, что стандартный формат в записи целых чисел в стандартной библиотеке С++ допускает указание явного +, и сразу понимаем, что никакого "арифметического выражения" в этой задаче вычислять не нужно вообще. Задача на самом деле состоит в том, чтобы просто просуммировать все целые числа в последовательности.

В рамках приведенных в условии жестких ограничений задача решается в одну строчку

C++
1
int r = std::accumulate(std::istream_iterator<int>(std::cin), std::istream_iterator<int>(), 0);
И никакой обработки никаких "знаков операций" делать не нужно вообще.

А вот какую-то обработку ошибочных вводов можно прикрутить как-то так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <numeric>
#include <iterator>
#include <iomanip>
#include <iostream>
 
int main() 
{
  std::cin >> std::noskipws;
  
  int r = std::accumulate(std::istream_iterator<int>(std::cin), std::istream_iterator<int>(), 0);
 
  if (std::cin.fail() && !std::cin.eof())
    std::cout << "Ошибочный ввод" << std::endl;
  else
    std::cout << r << std::endl;
}
Разумеется, это не предоставляет защиты от переполнений.

Добавлено через 2 минуты
Цитата Сообщение от gunslinger Посмотреть сообщение
Это вообще законно - "удалять массив", а потом его использовать?
Типа память еще не занята чем-то другим или как это работает?
Либо мне просто повезло?
Нет, разумеется. Не только использовать, а вообще даже смотреть в сторону указателя, к которому был применен delete - это UB. То есть return val - это уже UB.
1
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
31.05.2024, 21:38
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
return val - это уже UB.
C++
1
2
3
4
5
6
7
8
int* foo(){
   int *val = new int[5];
   delete [] val;
   return val;
}
int main(){
   foo();
}
И где же здесь UB ?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13177 / 6813 / 1821
Регистрация: 18.10.2014
Сообщений: 17,238
31.05.2024, 21:58
Цитата Сообщение от SmallEvil Посмотреть сообщение
И где же здесь UB ?
Как я уже сказал выше, return val; - использование invalid pointer value.

Однако тут стоит поправиться, что начиная с C++14 применение lvalue-to-rvalue conversion к invalid pointer value приводит к implementation-defined behavior, а не к UB. С оговоркой "Some implementations might define that copying an invalid pointer value causes a system-generated runtime fault." То есть диапазон implementation-defined behavior подчеркнуто включает в себя возможность падения программы из-за этого return val;.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
31.05.2024, 21:58
Помогаю со студенческими работами здесь

Вычислить арифметическое выражение
Добрый день. Есть такой код #include &lt;iostream&gt; using namespace std; int main() { float a; a=1+(5/13)*(2-1); ...

Вычислить арифметическое выражение
Помогите пожалуйста :boredom: Нужно разработать консольное приложение для вычисления арифметического выражения. Использовать функции...

Вычислить арифметическое выражение
Вычислить:

вычислить арифметическое выражение
вычислить арифметическое выражение y=A*B+tg(A) заранее большое спасибо!

Как вычислить арифметическое выражение?
Помогите пожалуйста решить задачу на экзамен! Вычисление арифметического выражения. Арифметическое выражение вводится в виде...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
1С: Контроль уникальности заводского номера
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере документа выдачи шин для спецтехники с табличной частью. Данные берутся из регистра сведений, по которому настроено. . .
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 22.03.2026
e7EYtONaj8Y Z4Tv2zpXVVo https:/ / github. com/ shumilovas/ med2. git
1С: Программный отбор элементов справочника по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор по наименованию группы. . .
Как я обхитрил таблицу Word
Alexander-7 21.03.2026
Когда мигает курсор у внешнего края таблицы, и нам надо перейти на новую строку, а при нажатии Enter создается новый ряд таблицы с ячейками, то мы вместо нервных нажатий Энтеров мы пишем любые буквы. . .
Krabik - рыболовный бот для WoW 3.3.5a
AmbA 21.03.2026
без регистрации и смс. Это не торговля, приложение не содержит рекламы. Выполняет свою непосредственную задачу - автоматизацию рыбалки в WoW - и ничего более. Однако если админы будут против -. . .
1С: Программный отбор элементов справочника по значению перечисления
Maks 21.03.2026
Установка программного отбора элементов справочника "Сотрудники" из модуля формы документа. В качестве фильтра для отбора служит значение перечислений. / / Событие "НачалоВыбора" реквизита на форме. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru