字符串问题

时间:2010-02-15 12:37:13

标签: c#

我正在设计关系计算器。

如果用户提供了类似-3.33 + 44 * 456 / 2.2-3 + 4 ....

的字符串

我想将它存储在字符串数组中

-3.33

44

*

456

/

2.2

-3

4

...... (即*,/,+ ve值,-ve值单独并按顺序排列成字符串数组)

这是我写的代码:

string a = "-3.33+44*456/2.2-3";

string[] ip = new string[25];
        int k = 0;


            for (int i = 0; i < a.Length; i++)
            {
                if (a.Substring(i, 1) == "+" || a.Substring(i, 1) == "-" || a.Substring(i, 1) == "*" || a.Substring(i, 1) == "/" || a.Substring(i, 1) == "^")
                {
                    for (int j = i + 1; j < a.Length; j++)
                    {
                        if (a.Substring(j, 1) == "+" || a.Substring(j, 1) == "-" || a.Substring(j, 1) == "*" || a.Substring(j, 1) == "/" || a.Substring(j, 1) == "^")
                        {
                            if (a.Substring(i, 1) == "+" || a.Substring(i, 1) == "-")
                            {
                                ip[k] = a.Substring(i, j-i);
                                k++;
                            }
                            else
                            {
                                ip[k] = a.Substring(i, 1);
                                k++;
                                ip[k] = a.Substring(i + 1, (j -i)-1);
                                k++;
                            }
                            i = j;
                            break;
                        }
                    }
                }

            }

但它不能正常工作: 它只在数组中存储一个元素。

从最近两天开始,我正在刹车。 请帮我。 谢谢。

4 个答案:

答案 0 :(得分:14)

你从一个完全错误的结局接近问题。你需要的是一个tokenizer和一个解析器。您可以手动编写,也可以使用许多所谓的“编译器编译器”。

您还可以尝试Irony

namespace Irony.Samples {
  // This grammar describes programs that consist of simple expressions and assignments
  // for ex:
  // x = 3
  // y = -x + 5
  //  the result of calculation is the result of last expression or assignment.
  //  Irony's default  runtime provides expression evaluation. 
  //  supports inc/dec operators (++,--), both prefix and postfix,
  //  and combined assignment operators like +=, -=, etc.

  [Language("ExpressionEvaluator", "1.0", "Multi-line expression evaluator")]
  public class ExpressionEvaluatorGrammar : Irony.Parsing.Grammar {
    public ExpressionEvaluatorGrammar() {

      // 1. Terminals
      var number = new NumberLiteral("number");
      //Let's allow big integers (with unlimited number of digits):
      number.DefaultIntTypes = new TypeCode[] { TypeCode.Int32, TypeCode.Int64, NumberLiteral.TypeCodeBigInt };
      var identifier = new IdentifierTerminal("identifier");
      var comment = new CommentTerminal("comment", "#", "\n", "\r"); 
      //comment must to be added to NonGrammarTerminals list; it is not used directly in grammar rules,
      // so we add it to this list to let Scanner know that it is also a valid terminal. 
      base.NonGrammarTerminals.Add(comment);

      // 2. Non-terminals
      var Expr = new NonTerminal("Expr");
      var Term = new NonTerminal("Term");
      var BinExpr = new NonTerminal("BinExpr", typeof(BinExprNode));
      var ParExpr = new NonTerminal("ParExpr");
      var UnExpr = new NonTerminal("UnExpr", typeof(UnExprNode));
      var UnOp = new NonTerminal("UnOp");
      var BinOp = new NonTerminal("BinOp", "operator");
      var PostFixExpr = new NonTerminal("PostFixExpr", typeof(UnExprNode));
      var PostFixOp = new NonTerminal("PostFixOp");
      var AssignmentStmt = new NonTerminal("AssignmentStmt", typeof(AssigmentNode));
      var AssignmentOp = new NonTerminal("AssignmentOp", "assignment operator");
      var Statement = new NonTerminal("Statement");
      var ProgramLine = new NonTerminal("ProgramLine");
      var Program = new NonTerminal("Program", typeof(StatementListNode));

      // 3. BNF rules
      Expr.Rule = Term | UnExpr | BinExpr | PostFixExpr;
      Term.Rule = number | ParExpr | identifier;
      ParExpr.Rule = "(" + Expr + ")";
      UnExpr.Rule = UnOp + Term;
      UnOp.Rule = ToTerm("+") | "-" | "++" | "--";
      BinExpr.Rule = Expr + BinOp + Expr;
      BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "**";
      PostFixExpr.Rule = Term + PostFixOp;
      PostFixOp.Rule = ToTerm("++") | "--";
      AssignmentStmt.Rule = identifier + AssignmentOp + Expr;
      AssignmentOp.Rule = ToTerm("=") | "+=" | "-=" | "*=" | "/=";
      Statement.Rule = AssignmentStmt | Expr | Empty;
      ProgramLine.Rule = Statement + NewLine;
      Program.Rule = MakeStarRule(Program, ProgramLine);
      this.Root = Program;       // Set grammar root

      // 4. Operators precedence
      RegisterOperators(1, "+", "-");
      RegisterOperators(2, "*", "/");
      RegisterOperators(3, Associativity.Right, "**");

      // 5. Punctuation and transient terms
      RegisterPunctuation("(", ")");
      RegisterBracePair("(", ")"); 
      MarkTransient(Term, Expr, Statement, BinOp, UnOp, PostFixOp, AssignmentOp, ProgramLine, ParExpr);

      //automatically add NewLine before EOF so that our BNF rules work correctly when there's no final line break in source
      this.LanguageFlags = LanguageFlags.CreateAst | LanguageFlags.NewLineBeforeEOF | LanguageFlags.CanRunSample; 

    }
  }
}//namespace

答案 1 :(得分:2)

这是我对这个问题的看法,它适用于测试用例,并且易于扩展/更改:

    {

        string InputString = "-3.33+44*456/2.2-3+4";
        string[] RetArray = InputString.Replace("-", " -").Replace("+", " +").Replace("*", " * ").Replace("/", " / ").Split(new Char[] { ' ' });

    }

只有一行。

修改:修正并验证。

答案 2 :(得分:0)

如果您只是尝试执行存储在字符串中的任意数学表达式,那么您一定要查看dotMath - Brief how-to

希望这有帮助!如果我不明白你的问题而且你正在尝试做一些更复杂的事情,这不会解决,请告诉我!

答案 3 :(得分:0)

不是为你重写代码,我只是指出你有几个错误(见评论):

string a = "-3.33+44*456/2.2-3"; 

string[] ip = new string[25]; 
    int k = 0; 


        for (int i = 0; i < a.Length; i++) 
        { 
            if (a.Substring(i, 1) == "+" || a.Substring(i, 1) == "-" || a.Substring(i, 1) == "*" || a.Substring(i, 1) == "/" || a.Substring(i, 1) == "^") 
            { 
                for (int j = i + 1; j <= a.Length; j++) // a.Length has to be included so the last element gets added
                { 
                    // allow the end of the string as an option
                    if (j == a.Length || a.Substring(j, 1) == "+" || a.Substring(j, 1) == "-" || a.Substring(j, 1) == "*" || a.Substring(j, 1) == "/" || a.Substring(j, 1) == "^") 
                    { 
                        if (a.Substring(i, 1) == "+" || a.Substring(i, 1) == "-") 
                        { 
                            ip[k] = a.Substring(i, j-i); 
                            k++; 
                        } 
                        else 
                        { 
                            ip[k] = a.Substring(i, 1); 
                            k++; 
                            ip[k] = a.Substring(i + 1, (j -i)-1); 
                            k++; 
                        }
                        i = j - 1; // i gets incremented in the for loop, so subract 1 here
                        break; 
                    } 
                } 
            } 

        }