Обратная польская запись C# не работает правильно
Я пишу RPN, со структурограммой.
Новейшая проблема: теперь она работает неправильно.
Если входная строка "5 + ((1 + 2) * 4) - 3"
Мой вывод: 5 1 2 + 4 * 3 - +
Я должен получить этот результат: 5 1 2 + 4 * + 3 -
Отредактировал источник
* Это была первоначальная проблема, но помогла мне, и теперь исправлены оригинальные ошибки: *,
При отладке, когда цикл или int i = 12, значение c равно 0\0 или что-то еще, и это значение добавляется в выходную строку (имя: формула) в виде скобки '('. И я не знаю почему. И последний символ операции "-" , не добавляется (или не просматривается) в конец строки вывода (формула). Я ошибся из-за этой проблемы, вызванной символом "(". Я попытался запустить программу с другим входным значением строки, но всегда ставьте '(' на мою строку, и я не знаю почему... Я видел, что это было независимо от числа скобок. Всегда только один '(' добавить к моей строке... *) Да, в английский LengyelFormula = rpn (это венгерский) *
static void Main(string[] args)
{
String str = "5 + ( ( 1 + 2 ) * 4 ) −3";
String result=LengyelFormaKonvertalas(str);
Console.WriteLine(result.ToString());
Console.ReadLine();
}
static String LengyelFormaKonvertalas(String input) // this is the rpn method
{
Stack stack = new Stack();
String str = input.Replace(" ",string.Empty);
StringBuilder formula = new StringBuilder();
for (int i = 0; i < str.Length; i++)
{
char x=str[i];
if (x == '(')
stack.Push(x);
else if (IsOperandus(x)) // is it operand
{
formula.Append(x);
}
else if (IsOperator(x)) // is it operation
{
if (stack.Count>0 && (char)stack.Peek()!='(' && Prior(x)<=Prior((char)stack.Peek()) )
{
char y = (char)stack.Pop();
formula.Append(y);
}
if (stack.Count > 0 && (char)stack.Peek() != '(' && Prior(x) < Prior((char)stack.Peek()))
{
char y = (char)stack.Pop();
formula.Append(y);
}
stack.Push(x);
}
else
{
char y=(char)stack.Pop();
if (y!='(')
{
formula.Append(y);
}
}
}
while (stack.Count>0)
{
char c = (char)stack.Pop();
formula.Append(c);
}
return formula.ToString();
}
static bool IsOperator(char c)
{
return (c=='-'|| c=='+' || c=='*' || c=='/');
}
static bool IsOperandus(char c)
{
return (c>='0' && c<='9' || c=='.');
}
static int Prior(char c)
{
switch (c)
{
case '=':
return 1;
case '+':
return 2;
case '-':
return 2;
case '*':
return 3;
case '/':
return 3;
case '^':
return 4;
default:
throw new ArgumentException("Rossz paraméter");
}
}
}
3 ответа
using System;
using System.Collections.Generic;
using System.Text;
class Sample {
static void Main(string[] args){
String str = "5 + ( ( 1 + 2 ) * 4 ) -3";
String result=LengyelFormaKonvertalas(str);
Console.WriteLine(result);
Console.ReadLine();
}
static String LengyelFormaKonvertalas(String input){
Stack<char> stack = new Stack<char>();
String str = input.Replace(" ", string.Empty);
StringBuilder formula = new StringBuilder();
for (int i = 0; i < str.Length; i++){
char x=str[i];
if (x == '(')
stack.Push(x);
else if (x == ')'){
while(stack.Count>0 && stack.Peek() != '(')
formula.Append(stack.Pop());
stack.Pop();
} else if (IsOperandus(x)){
formula.Append(x);
} else if (IsOperator(x)) {
while(stack.Count>0 && stack.Peek() != '(' && Prior(x)<=Prior(stack.Peek()) )
formula.Append(stack.Pop());
stack.Push(x);
}
else {
char y= stack.Pop();
if (y!='(')
formula.Append(y);
}
}
while (stack.Count>0) {
formula.Append(stack.Pop());
}
return formula.ToString();
}
static bool IsOperator(char c){
return (c=='-'|| c=='+' || c=='*' || c=='/');
}
static bool IsOperandus(char c){
return (c>='0' && c<='9' || c=='.');
}
static int Prior(char c){
switch (c){
case '=':
return 1;
case '+':
return 2;
case '-':
return 2;
case '*':
return 3;
case '/':
return 3;
case '^':
return 4;
default:
throw new ArgumentException("Rossz parameter");
}
}
}
В IsOperator вы проверяете c == '-'.
Но в строке вы пишете −3.
- не тот же персонаж, что и -
Я ничего не знаю о польском, поэтому, может быть, я что-то упускаю, но поэтому не выводится оператор "-", он не проходит проверку IsOperator и переходит в предложение else, которое не добавляет его в формулу.
Когда вы получаете )
, вы должны вытолкнуть все операторы и добавить их в формулу, пока не достигнете (
и вставьте это '(' также.
Когда вы получаете оператор, вы должны только вытолкнуть стек и добавить этот оператор в формулу, если его приоритет больше или равен приоритету x
, Ваша вторая проверка избыточна, потому что она уже покрыта первой.
Как правило: попробуйте свою программу с помощью простых входных данных, таких как 1+2+3
, 1+2-3
, 1*2+3
а также 1+2*3
и посмотреть, если вы получите правильный результат. Такое систематическое тестирование должно помочь вам быстрее находить ошибки.