|
|
bet | 17/23 | Sana | 21.03.2020 | Hajmi | 326,03 Kb. | | #42712 |
| Bog'liq Короткие примеры C
else // Ошибка ввода.
break;
}
}
else // Ошибка ввода.
break;
}
// Вернуть текущую вершину стека.
if (operands.empty()) // Стек пуст.
{
Stack_underflow_error:
cerr << "stack underflow\n";
return 0.;
}
return operands.top();
}
int main()
{
while (true)
{
double answer = postfix();
// Сброс потока.
cin.clear();
cin.ignore(cin.rdbuf()->in_avail());
cin.sync();
// Вывод ответа.
cout << "answer = " << answer << endl;
}
return EXIT_SUCCESS;
}
0790-prefix_calc_stack_std.cpp
// prefix_calc_stack_std.cpp
// Реализация калькулятора с поддержкой четырёх арифметических действий,
// принимающего выражения в префиксной записи (она же "польская нотация").
// Грамматика выражения: операция операнд операнд, где операнд может быть числом или опять выражением
// Например, + * 2 3 4 ==> (2 * 3) + 4 == 10
// Для хранения промежуточных данных используются стеки на основе стандартного класса stack.
#include
#include // strchr
#include
using namespace std;
// Читает выражение с cin, возвращает вычисленное значение выражения.
double prefix()
{
stack<char> ops; // Стек отложенных значений op.
stack<double> xs; // Стек отложенных значений x.
stack<bool> has_x; // Стек признака "операция уже имеет первый операнд в стеке xs".
double y = 0.; // Второй операнд.
do
{
char op;
if (cin >> op)
{
if (strchr("+-*/", op)) // Считали знак операции.
{
ops.push(op);
has_x.push(false); // Новая операция -- ещё нет ни одного операнда.
}
else // не знак операции -- вернуть считанный символ и прочитать число
{
cin.unget();
if (cin >> y) // Считали число.
{
// Можно выполнить "свёртку" операций, для которых есть первый операнд.
while (!ops.empty() && has_x.top())
{
// Извлечь из стека первый аргумент операции.
const auto x = xs.top();
xs.pop();
switch (ops.top())
{
case '+': y = x + y; break;
case '-': y = x - y; break;
case '*': y = x * y; break;
case '/': y = x / y; break;
}
// Убрать вычисленную операцию.
ops.pop();
has_x.pop();
}
// Получили первый операнд некоторой операции?
if (!ops.empty())
{
has_x.top() = true;
xs.push(y);
}
}
}
}
else
{
// Ошибка ввода.
cerr << "input error\n";
break;
}
} while (!ops.empty()); // Продолжать, пока есть ещё операции.
return y;
}
int main()
{
while (true)
{
double answer = prefix();
// Сброс потока ввода.
cin.clear();
cin.ignore(cin.rdbuf()->in_avail());
cin.sync();
// Вывод ответа.
cout << "answer = " << answer << endl;
}
return EXIT_SUCCESS;
}
0800-infix_calc.cpp
// infix_calc.cpp
// Инфиксный калькулятор без учёта приоритетов операций и без поддержки скобок.
// Пример: 2+2*2 ==> 8 (выполняет операции подряд).
// Рекурсивная реализация.
#include
using namespace std;
// Читает из потока cin, возвращает значение выражения.
double infix(double x)
{
char op;
if (cin >> op)
{
double y;
if (cin >> y)
{
switch (op)
{
case '+': return infix(x + y);
case '-': return infix(x - y);
case '*': return infix(x * y);
case '/': return infix(x / y);
default:
cerr << "unknown operation '" << op << "'\n";
return x;
}
}
else
cerr << "number expected\n";
}
return x;
}
double infix()
{
double x;
if (cin >> x)
return infix(x);
cerr << "number expected\n";
return 0.;
}
int main()
{
while (true)
{
double answer = infix();
cin.clear();
cin.ignore(cin.rdbuf()->in_avail());
cin.sync();
cout << "answer = " << answer << endl;
}
return EXIT_SUCCESS;
}
0801-infix_calc_tc.cpp
// infix_calc_tc.cpp
// Инфиксный калькулятор без учёта приоритетов операций и без поддержки скобок.
// Пример: 2+2*2 ==> 8 (выполняет операции подряд).
// Получен из infix_calc.cpp путём замены рекурсии на итерацию
// (нетрудно заметить, что в рекурсивном варианте только хвостовые вызовы).
#include
using namespace std;
// Читает из потока cin, возвращает значение выражения.
double infix(double x)
{
char op;
while (cin >> op)
{
double y;
if (cin >> y)
{
switch (op)
{
case '+': x = x + y; break;
case '-': x = x - y; break;
case '*': x = x * y; break;
case '/': x = x / y; break;
default:
cerr << "unknown operation '" << op << "'\n";
return x;
}
}
else
cerr << "number expected\n";
}
return x;
}
double infix()
{
double x;
if (cin >> x)
return infix(x);
cerr << "number expected\n";
return 0.;
}
int main()
{
while (true)
{
double answer = infix();
cin.clear();
cin.ignore(cin.rdbuf()->in_avail());
cin.sync();
cout << "answer = " << answer << endl;
}
return EXIT_SUCCESS;
}
0802-infix_calc_tc_2.cpp
// infix_calc_tc_2.cpp
// Инфиксный калькулятор без учёта приоритетов операций и без поддержки скобок.
// Пример: 2+2*2 ==> 8 (выполняет операции подряд).
// Получен из infix_calc_tc.cpp слиянием двух функций infix в одну
// (без рекурсии два варианта уже не нужны).
#include
using namespace std;
// Читает из потока cin, возвращает значение выражения.
double infix()
{
double x;
if (!(cin >> x))
{
cerr << "number expected\n";
return 0.;
}
for (char op; cin >> op;)
{
double y;
if (cin >> y)
{
switch (op)
{
case '+': x = x + y; break;
case '-': x = x - y; break;
case '*': x = x * y; break;
case '/': x = x / y; break;
default:
cerr << "unknown operation '" << op << "'\n";
return x;
}
}
else
cerr << "number expected\n";
}
return x;
}
int main()
{
while (true)
{
double answer = infix();
cin.clear();
cin.ignore(cin.rdbuf()->in_avail());
cin.sync();
cout << "answer = " << answer << endl;
}
return EXIT_SUCCESS;
}
0810-infix_calc_p.cpp
// infix_calc_p.cpp
// Инфиксный калькулятор без учёта приоритетов операций, но с поддержкой скобок.
// Пример: 2+(2*2) ==> 6.
// Грамматика:
// Терм --> Число | '(' Выражение ')' // term
// Выражение --> Терм { Операция Терм } // infix
// Рекурсивная реализация на основе грамматики.
#include
using namespace std;
// Вспомогательная функция:
// посмотреть следующий непробельный символ в потоке cin, не извлекая его.
// (Пробельные символы пропускаются. Возвращает EOF если поток закончился.)
char peek()
{
char ch = EOF;
if (cin >> ch)
cin.unget();
return ch;
}
// Вспомогательная функция для установки ошибки.
void error(const char *message)
{
cerr << message;
cin.setstate(ios::failbit);
}
double infix();
// Терм --> Число | '(' Выражение ')'
double term()
{
double result = 0.;
switch (peek()) // Ожидается число или открывающая скобка.
{
case '-': case '+': case '.':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
if (!(cin >> result))
error("number expected\n");
return result;
case '(':
cin.ignore(); // Пропустить '('.
result = infix();
if (peek() != ')')
error("unmatched '(' found\n");
else
cin.ignore(); // Пропустить ')'.
return result;
case ')':
error("unmatched ')' found\n");
return 0.;
default:
error("term expected, '");
cerr << peek() << "' found\n";
return 0.;
}
}
// Выражение --> Терм { Операция Терм }
double infix()
{
double x = term(), y = 0.;
while (true)
{
switch (char op = peek()) // Ожидается операция.
{
case '+': case '-': case '*': case '/':
cin.ignore();
y = term(); // Получить второй операнд.
Do'stlaringiz bilan baham: |
|
|