Я думаю, вы понимаете, что пропустили второй операнд, потому что, как только вы видите оператор, вы пытаетесь вытолкнуть в стек 2 значения.В примере вы легко заметили, что этого никогда не произойдет (этот стек будет иметь 2 переменные, поскольку оператор является двоичным).Так что вы должны кое-как сохранить вторую переменную и оператор и попытаться оценить их позже.Ниже может быть полезен алгоритм, понимайте, что он является базовым для простых операторов.
- Начните с 2 стеков, одной из переменных и одного из операторов.
- Прежде чем помещать оператор в стек операторов, проверьте приоритет / приоритет.Если приоритет существующего оператора над стеком выше или равен тому, который вы собираетесь выдвинуть, тогда начните вытягивать стек для оператора и переменных.
- Наконец, когда вы прошли всю строку, проверьте свой стек на наличие оставшегося оператора, завершите оценку этого, и вы получите конечные результаты.
In 2 *3 + 4, когда вы достигнете +, у вас будет 2,3 в одном стеке и * в другом.Теперь, пытаясь нажать +, вы увидите существующий * в стеке с более высоким приоритетом, так что вытолкните его, так как его двоичный оператор вытолкнет 2 переменные, создайте выражение, оцените его и поместите в стек переменных (так как результатдля оценки будет использоваться переменная / число), а затем снова посмотреть, есть ли еще операторы с более высоким приоритетом в стеке.
При добавлении решения, пожалуйста, имейте в виду: 1. Приоритет оператора / какой тип оператора(Унарный / двоичный) / является ли он симметричным / несимметричным (+ симметричен, но не имеет мощности) будет играть важную роль.
Старайтесь не изменять переменную i внутри цикла, рано или поздно вы запуститев беду.
Данный код работает только для 2 приведенных примеров, и часть для проверки приоритета пуста, но может быть заполнена на основе существующего кода.
Вам потребуется изменить переменнуюnaming loigc, в случае смешанных имен, таких как 'A2', ваша текущая логика потерпит неудачу.
string tree = "AB-12-AC-14";
Stack<BaseNode> TreeStack = new Stack<BaseNode>();
Stack<BaseNode> TreeStack1 = new Stack<BaseNode>();
BaseNode temp1 = new BaseNode();
BaseNode temp2 = new BaseNode();
for (int i = 0; i < tree.Length; i++)
{
VariableNode varNode = new VariableNode();
NumericalNode numNode = new NumericalNode();
if (CheckExpressions(tree[i])) // if the character is an operator
{
OperatorNode expression = new OperatorNode(tree[i]);
//check priority should pass the current operator to really check for priority
if (CheckPriority() || TreeStack1.Count == 0)
{
TreeStack1.Push(expression);
}
else
{
// assuming binary operators only
temp1 = TreeStack.Pop();
temp2 = TreeStack.Pop();
expression.Right = temp1;
expression.Left = temp2;
TreeStack.Push(expression);
// need to check if there are more operators on stack1 are they higher priority then current operator
// if they are then pop them and apply them too
}
}
else if (!CheckExpressions(tree[i]))
{
if (Char.IsLetter(tree[i]))
{
while (Char.IsLetter(tree[i])) // for the variable node
{
varNode.name += tree[i];
if (i + 1 == tree.Length)
{
break;
}
i++;
}
TreeStack.Push(varNode);
if (i + 1 != tree.Length)
{
i--;
}
}
else if (Char.IsDigit(tree[i])) // for constant value
{
int zero = 0; // for appending the numbers to combine them
while (i < tree.Length && Char.IsDigit(tree[i])) // need to check for length otherwise index will go out of bounds
{
if (zero == 0)
{
zero = tree[i] - '0';
}
else
{
zero = int.Parse(zero.ToString() + tree[i].ToString());
}
if (i < tree.Length)
{
i++;
}
}
if (i + 1 != tree.Length)
{
i--;
}
numNode.number = zero;
TreeStack.Push(numNode);
}
}
}
// finish any remaining operators and push the final expression on the stack
while (TreeStack1.Count!=0)
{
OperatorNode expression1 = new OperatorNode(((OperatorNode)TreeStack1.Pop()).v);
expression1.Right = TreeStack.Pop();
expression1.Left = TreeStack.Pop();
TreeStack.Push(expression1);
}