2

現在、逆ポーランド記法計算機を使用しています。完全に機能していますが、値の計算に使用されるテキスト入力で問題が発生しています。のような式を導入すると、プログラムが壊れ( 8 5 + ) 6 * =ます。入力値に表示される括弧を単に無視する方法はありますか? また、私のプログラムは各数値間のスペースに応じて分割されますが、オペランドまたは括弧の間にスペースを追加すると、それも壊れます: (8 5 +)6 * =. 無効な数式12 + =(数値が欠落している) の場合、それらを無視して、出力 textBox にエラー メッセージを表示するだけです。

補足: すべての数式は末尾の によってトリガーされ=ます。

コード

namespace rpncalc
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

      private string inputValue = "";

        private void RPNCalc(string rpnValue)
        {
            Stack<int> stackCreated = new Stack<int>();
            stackCreated.Clear();
            string[] inputArray = rpnValue.Split();
            int end = inputArray.Length - 1;
            int numInput;
            int i = 0;

            do
            {
                if ("=+-*/%^".IndexOf(inputArray[i]) == -1)
                {
                    try
                    {
                        numInput = Convert.ToInt32(inputArray[i]);
                        stackCreated.Push(numInput);
                    }
                    catch
                    {
                        MessageBox.Show("Please check the input");
                    }
                }

                    else if (inputArray[i]== "+")
                    {
                        try
                        {
                            int store1 = stackCreated.Pop();
                            int store2 = stackCreated.Pop();
                            stackCreated.Push(store2 + store1);
                        }
                        catch
                        {
                        }
                    }

                    else if (inputArray[i]== "-")
                    {
                        try
                        {
                            int store1 = stackCreated.Pop();
                            int store2 = stackCreated.Pop();
                            stackCreated.Push(store2 - store1);
                        }
                        catch
                        {
                        }
                    }

                    else if (inputArray[i]== "%")
                    {
                        try
                        {
                            int store1 = stackCreated.Pop();
                            int store2 = stackCreated.Pop();
                            stackCreated.Push(store2 % store1);
                        }
                        catch
                        {
                        }
                    }

                    else if (inputArray[i]== "*")
                    {
                        try
                        {
                            int store1 = stackCreated.Pop();
                            int store2 = stackCreated.Pop();
                            stackCreated.Push(store2 * store1);
                        }
                        catch
                        {
                        }
                    }

                    else if (inputArray[i]== "/")
                    {
                        try
                        {
                            int store1 = stackCreated.Pop();
                            int store2 = stackCreated.Pop();
                            stackCreated.Push(store2 / store1);
                        }
                        catch
                        {
                        }
                    }

                    else if (inputArray[i] == "^")
                    {
                        try
                        {
                            int store1 = stackCreated.Pop();
                            int store2 = stackCreated.Pop();
                            stackCreated.Push((int)Math.Pow(store1, store2));

                        }
                        catch
                        {
                        }
                    }

            }
            while(i++ < end && inputArray[i]!= "=" && stackCreated.Count != 0);
            string result = inputValue + " " + stackCreated.Pop().ToString() + Environment.NewLine;
            TxtOutputBox.AppendText(result);
            TxtInputBox.Clear();

        }

        private void TxtOutputBox_TextChanged(object sender, EventArgs e)
        {

        }

        private void Btn_Calc_Click(object sender, EventArgs e)
        {
            inputValue = TxtInputBox.Text + " ";
            RPNCalc(inputValue);
        }
    }
}

ここに画像の説明を入力

4

3 に答える 3

1

まず、次のようなことをします

rpnValue = rpnValue.Replace(" ", "").Replace("(","").Replace(")","");

この質問に対するサムの回答が推奨するように、アルゴリズム全体を大幅に書き直す必要があります。問題は、スペースを削除する Replace(" ", "") 部分にあります。ただし、アルゴリズムは Split に依存して入力をトークン化します。その分割の前にスペースを削除すると、数値と演算子の配列を取得する代わりに、既存のコードでは処理できない単一の文字列が取得されます。さらに悪いことに、"12 3 * =" と "1 23 * =" の両方が "123*=" に変換されます !!!

大きな変更を避けるために、コードを次のように変更します。

Split の前に次のコードを挿入します。

rpnValue = rpnValue.Replace("("," ").Replace(")"," ");

これにより、要求どおりに括弧が無視されるようになりますが、(8 5 +)6 * = 機能するようになります。

そして、次の追加を行います。

                if (" \t\n\r".IndexOf(inputArray[i]) != -1) {
                       continue;
                } else if ("=+-*/%^".IndexOf(inputArray[i]) == -1)
                ...

また、ループの最後のコードも変更する必要があります。

        while (i++ < end && inputArray[i] != "=");
        if(stackCreated.Count != 1)
            MessageBox.Show("Please check the input");

それが役立つことを願っています:-)

------------------------------- 本当の答えはここまで ------------------ ----------------

追加の推奨事項: この質問はエラー報告の問題をカバーしていませんが、他にも気付きました: スタック上の操作は try catch ステートメントで囲まれており、catch 部分では何も起こりません。このようにして、不適切な形式の入力は適切にフラグ付けされません。これらの try catch ステートメントを削除し、関数の本体の周りに 1 つ置くことをお勧めします。

いくつかの楽しみ:私の目的は、尋ねられた非常に具体的な質問に答えるだけでした.正規表現に依存しません (計算される式が で終わらないことを除いて=)。

    private void RPNCalc(string rpnValue)
    {
        Stack<int> stackCreated = new Stack<int>();

        try {

            var tokens = rpnValue.Replace("(", " ").Replace(")", " ")
                                 .Split().Where(s => !String.IsNullOrWhiteSpace(s));

            foreach (var t in tokens) {

                try {

                    stackCreated.Push(Convert.ToInt32(t));

                } catch {

                    int store1 = stackCreated.Pop();
                    int store2 = stackCreated.Pop();

                    switch(t) {
                        case "+": store2 += store1; break;
                        case "-": store2 -= store1; break;
                        case "*": store2 *= store1; break;
                        case "/": store2 /= store1; break;
                        case "%": store2 %= store1; break;
                        case "^": store2 = (int) Math.Pow(store2, store1); break; /* was (int) Math.Pow(store1, store2); in the original code*/  
                        default: throw new Exception();
                    }

                    stackCreated.Push(store2);
                }
            }

            if(stackCreated.Count != 1)
                MessageBox.Show("Please check the input");
            else
                textBox1.Text =   stackCreated.Pop().ToString();

        } catch {
            MessageBox.Show("Please check the input");
        }
    }
于 2012-11-30T17:54:16.907 に答える
0

文字列から重要でない文字を削除する方法:

string str = inStr.Replace(" ", "").Replace("(","").Replace("etc.","");
于 2012-11-30T17:25:54.133 に答える
0

ちょっとした考え;

string input = @"( 8 5 + ) 6 *";
var tokens = Regex.Matches(input, @"(?<num>[0-9]+)|(?<op>[\+\-\*\/\^\%])").Cast<Match>()
                .Select(m=> String.IsNullOrEmpty(m.Groups["num"].Value)
                            ? new Tuple<string,string>("op",m.Groups["op"].Value)
                            : new Tuple<string,string>("num",m.Groups["num"].Value))
                .ToList();

var fxns = new Dictionary<string, Func<int, int, int>>()
{
    {"+",(i,j)=>j+i },
    {"-",(i,j)=>j-i },
    {"*",(i,j)=>j*i },
    {"/",(i,j)=>j/i },
    {"%",(i,j)=>j&i },
    {"^",(i,j)=>(int)Math.Pow(j,i) },
};

Stack<int> stack = new Stack<int>();

foreach (var token in tokens)
{
    if (token.Item1 == "num")
        stack.Push(int.Parse(token.Item2));
    else
        stack.Push(fxns[token.Item2](stack.Pop(), stack.Pop()));
}

int finalResult = stack.Pop();
于 2012-11-30T18:50:01.203 に答える