2010-02-15 5 views
2

Je suis dans un processus de conception de calculatrice relationnelle.Problème avec les chaînes

Si un utilisateur a fourni une chaîne comme -3,33 + 44 * 456/2.2-3 + 4 ....

Je veux stocker dans le tableau de chaîne comme

-3,33

+44

*

/

2,2

-3

+4

...... (qui est *, /, + ve valeur, la valeur -ve séparément et dans un ordre en série dans un tableau de chaînes)

Voici le code que j'ai écrit:

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; 
         } 
        } 
       } 

      } 

Mais sa ne fonctionne pas correctement: Son stockage d'un seul élément dans le tableau.

Depuis deux jours, je freine ma tête. S'il vous plaît aidez-moi. Merci.

Répondre

0

Plutôt que de réécrire votre code pour vous, je vais indiquer où vous avez quelques bugs (voir les commentaires):

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; 
        } 
       } 
      } 

     } 
14

Vous abordez le problème d'une façon complètement fausse. Ce dont vous avez besoin est un tokenizer et un analyseur. Vous pouvez les écrire à la main, ou vous pouvez utiliser l'un des nombreux "compilateurs-compilateurs".

Vous pouvez également essayer 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 
+0

Comment utiliser ce code? Comment pouvons-nous l'intégrer dans des formulaires Windows? – Gokul

+1

Un peu trop haut ne pensez-vous pas? – ChaosPandion

0

Si vous essayez juste d'exécuter des expressions mathématiques arbitraires stockées dans une chaîne, vous devriez vraiment regarder à dotMath-Brief how-to.

Espérons que cela aide! Si je n'ai pas compris votre question et que vous essayez de faire quelque chose de beaucoup plus compliqué que cela ne résoudrait pas, faites le moi savoir!

2

Ceci est mon point de vue sur cette question, il travaille pour le testcase et sont faciles à développer/changement:

{ 

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

    } 

Juste une ligne.

Édition: Fixe et vérifiée.

+0

Dans mon système, les chaînes ne sont pas reconnues. Ce code donne une erreur. J'utilise VS2008 – Gokul

+0

Erreur 'System.Linq.Strings 'est inaccessible en raison de son niveau de protection – Gokul

+0

quelle coque je fais maintenant? C'est l'erreur soulevée par mon VS2008. – Gokul

Questions connexes