Как создать математическое выражение из операторов и операндов в очереди

Я пытаюсь построить математическое выражение (включая скобки) с операторами и операндами, включенными в очередь.

Вот мой код:

string createExp (queue<char> q) {
string s;
string s1, s2;
char c;

while (!q.empty()) {

c = q.front();

if (c == 'x') {
s += "x";
q.pop();
}

else if (c == 'y') {
s += "y";
q.pop();
}

else if (c == 'a') {
s += "avg(";
q.pop();

s1 = createExp(q);
q.pop();
s2 = createExp(q);
q.pop();
s += s1;
s += ',';
s += s2;
s += ')';
}

else if (c == 's') {
s += "sin(pi*";
q.pop();
op++;
}
else if (c == 'c') {
s += "cos(pi*";
q.pop();
op++;
}
else {
s += "*";
q.pop();
}
}

while (op > cp) {
s += ")";
cp++;
}

return (s);
}

Как вы можете видеть, в случае усреднения (avg) я пытаюсь рекурсивно вызвать функцию, чтобы получить следующую последовательность значений.

Например, если моя очередь содержит следующие значения:

s m a y x y

Выражение должно быть таким:

грех (пи * (ср (у, х) * у)

Но мой код возвращает эту последовательность:

грех (пи ** ср (yyx) yyxyyx

Не могли бы вы помочь мне с этим?

Большое спасибо.

0

Решение

Эта часть обработки avg(-,-) ужасно сломан

s1 = createExp(q);
q.pop();
s2 = createExp(q);
q.pop();

Вы передаете очередь по значению, которая создает ее копию. Тогда вы не можете узнать, сколько раз рекурсия выдвигалась в очередь. Но вы волшебным образом предполагаете, что вы должны удалить ровно один элемент. Что если в одном из аргументов есть вызов функции или оператор.

Что еще хуже, рекурсия обрабатывает всю остальную часть очереди, а не только одно выражение.

3

Другие решения

** исходит от обоих m в строке, и вы явно пишете sin(pi* в коде.

Кроме того, рекурсия в AVG (при создании s1 кажется, индексировать все выражение, так что вы получаете yyx). Вы должны убедиться, что он читает только 1 полное выражение из стека, а не все остальное. Это сложно, потому что вы должны сказать разницу между avg(x,y) а также avg(x+y,y*x) например.

1

Я сделал небольшую модификацию вашего кода, и она отлично работает:

int cp = 0,  op = 0;

std::string createExp(std::queue< char >& q)
{
std::string s;
std::string s1, s2;
char c;

while (!q.empty())
{
c = q.front();

if (c == 'x')
{
s += "x";
q.pop();
}
else if (c == 'y')
{
s += "y";
q.pop();
}
else if (c == 'a')
{
s += "avg(";
q.pop();

s1 = q.front(); // here
q.pop();
s2 = q.front(); // and here
q.pop();
s += s1;
s += ',';
s += s2;
s += ')*';
}
else if (c == 's')
{
s += "sin(pi*";
q.pop();
op++;
}
else if (c == 'c')
{
s += "cos(pi*";
q.pop();
op++;
}
else
{
//             s += "*";
q.pop();
}
}

while (op > cp)
{
s += ")";
cp++;
}

return (s);
}

Но это будет работать, только если ваш оператор всегда *, Если вам нужны и другие операторы, то вам нужна более сложная вещь.

0

Вот мое последнее рекурсивное решение:

int cp = 0,  op = 0;

string recursiveExp (queue<char>& q) {
char e;

if (!q.empty()) {
e = q.front();
if (e == 'x' || e == 'y') {
q.pop();
s += e;
}

else if (e == 's') {
q.pop();
s += "sin(pi*";
op++;
recursiveExp(q);
s += ")";
cp++;
}

else if (e == 'c') {
q.pop();
s += "cos(pi*";
op++;
recursiveExp(q);
s += ")";
cp++;
}

else if (e == 'a') {
q.pop();
s += "avg(";
op++;
recursiveExp(q);
s += ",";
recursiveExp(q);
s += ")";
cp++;
}

else if (e == 'm'){
q.pop();
s += "(";
op++;
recursiveExp(q);
s += "*";
recursiveExp(q);
s += ")";
cp++;
}
}
return s;
}

Спасибо всем 🙂

0
По вопросам рекламы [email protected]