Как добавить многозначные целые числа в обратном польском калькуляторе
// FILE: calc.h
#include <iostream>
#include <stack> // Uses STL
#include <string> // Uses STL
using namespace std;
void evaluate_stack_tops(stack<double> & numbers, stack<char> & operations);
double read_and_evaluate(string line)
{
const char RIGHT_PARENTHESIS = ')';
stack<double> numbers; // local stack object
stack<char> operations; // local stack object
double number;
char symbol;
size_t position = 0;
while (position < line.length())
{
if (isdigit(line[position]))
{
number = line[position++] - '0'; // get value
numbers.push(number);
}
else if (strchr("+-*/", line[position]) != NULL)
{
symbol = line[position++];
operations.push(symbol);
}
else if (line[position] == RIGHT_PARENTHESIS)
{
position++;
evaluate_stack_tops(numbers, operations);
}
else
position++;
}
if (!operations.empty())
evaluate_stack_tops(numbers, operations);
return numbers.top();
}
void evaluate_stack_tops(stack<double> & numbers, stack<char> & operations)
{
double operand1, operand2;
operand2 = numbers.top();
numbers.pop();
operand1 = numbers.top();
numbers.pop();
switch (operations.top())
{
case '+': numbers.push(operand1 + operand2); break;
case '-': numbers.push(operand1 - operand2); break;
case '*': numbers.push(operand1 * operand2); break;
case '/': numbers.push(operand1 / operand2); break;
}
operations.pop();
}
// FILE: Use_Stack.cpp
#include <iostream>
using namespace std;
#include "calc.h"
int main()
{
double answer;
string line;
cout << "Type a fully parenthesized arithmetic expression (SINGLE DIGITS ONLY!):\n";
getline(cin, line);
answer = read_and_evaluate(line);
cout << "That evaluates to " << answer << endl;
system("pause");
return 0;
}
Все работает, и я могу ввести простые вещи, такие как "2 4 3 * + 7 - 2 +", но если бы я хотел ввести что-то вроде "123 60 +", это не сработало бы. я разделил его на два заголовочных файла. Может кто-нибудь дать мне подсказку о том, как принимать многозначные целые числа?
2 ответа
Один из способов решения этой проблемы состоит в том, чтобы найти номер, вместо того, чтобы предполагать, что он состоит только из одной цифры, и использовать цикл для сбора всех других цифр, которые являются частью номера. Цикл завершается, когда встречается не цифра или пробел.
Лучший способ сделать это - токенизировать входную строку, используя stringstream
, В этом сценарии вы должны поместить всю строку ввода в строку, а затем использовать цикл while, подобный следующему:
stringstream ss(line);
string token;
while (ss >> token) {
// do stuff with token
}
RPN работает, имея стек значений, которыми вы манипулируете. Учитывая вход "13"
, манипуляция должна была пойти от top=1
в top=13
довольно просто: top = 10 * top + digit