假设一个字符串str="4*36+7+88/12^2",C#如何直接计算出这个字符串变量str的算术值。

解决方案 »

  1.   

    public static object Eval(string AExpression)
    {
        try
        {
            return new DataTable().Compute(AExpression, "");
        }
        catch
        {
            return null;
        }
    }
      

  2.   

    这个应该可以满足你的基本要求!!   
      #include   <stdio.h>   
      #include   <stdlib.h>   
      #define   init_size   10   
      #define   pp_size   2   
      int   i=0;   
      typedef   struct   
        {char   *base;   
          char   *top;   
          int   size;   
        }optr;   
      typedef   struct   
          {int   *base;   
            int   *top;   
            int   size;   
          }oped;   
      char   lable[8][8]={'   ','+','-','*','/','(',')','#',   
          '+','>','>','<','<','<','>','>',   
          '-','>','>','<','<','<','>','>',   
          '*','>','>','>','>','<','>','>',   
          '/','>','>','>','>','<','>','>',   
          '(','<','<','<','<','<','=','   ',   
          ')','>','>','>','>','   ','>','>',   
          '#','<','<','<','<','<','   ','='   
          };   
        
      void   init_oped(oped   *s)   
                {s->base=(int   *)malloc(init_size*sizeof(int));   
                  if(!s->base)   {printf("init   error!");exit(0);}   
                  s->top=s->base;   
                  s->size=init_size;   
                  }   
        
      void   init_optr(optr   *s)   
                {s->base=(char   *)malloc(init_size*sizeof(char));   
                  if(!s->base)   {printf("init   error!");exit(0);}   
                  s->top=s->base;   
                  s->size=init_size;   
                  }   
      void   push_oped(oped   *s,int   e)   
                {if(s->top-s->base>=s->size)   
                    {s->base=(int   *)realloc(s->base,(init_size+pp_size)*sizeof(int));   
      if(!s->base)   {printf("puss_oped   error!");exit(0);}   
      s->top=s->base+s->size;   
      s->size+=pp_size;   
      }   
      *s->top=e;   
      s->top++;   
                }   
      void   push_optr(optr   *s,char   e)   
                {if(s->top-s->base>=s->size)   
                    {s->base=(char   *)realloc(s->base,(init_size+pp_size)*sizeof(char));   
      if(!s->base)   {printf("push_optr   error!");exit(0);}   
      s->top=s->base+s->size;   
      s->size+=pp_size;   
      }   
      *s->top=e;   
      s->top++;   
                }   
      char   pop_optr(optr   *s)   
                {char   ch;   
                  if(s->top==s->base)   {printf("optr-stack   NULL!");exit(0);}   
                  ch=*(--s->top);   
                  return   ch;   
                }   
        
      int   pop_oped(oped   *s)   
                {int   ch;   
                  if(s->top==s->base)   {printf("oped-stack   NULL!");exit(0);}   
                  ch=*(--s->top);   
                  return   ch;   
                }   
      char   gettop(optr   *s)   
                {char   ch;   
                  if(s->top==s->base)   {printf("gettop   stack   NULL   error!");exit(0);}   
                  ch=*(s->top-1);   
                  return   ch;   
                }   
      char   precede(char   x,char   y)   
                {char   ch;   
                  int   i,j;   
                  for(i=0;i<8;i++)   
                    if(lable[i][0]==x)   break;   
                  for(j=0;j<8;j++)   
                    if(lable[0][j]==y)   break;   
                  ch=lable[i][j];   
                  return   ch;   
                }   
      int   operate(int   x,char   ch,int   y)   
              {int   sum=0;   
                switch   (ch)   
                {case   '+':sum=x+y;break;   
                  case   '-':sum=x-y;break;   
                  case   '*':sum=x*y;break;   
                  case   '/':sum=x/y;break;   
                  }   
                return   sum;   
              }   
      main()   
      {optr   *p;   
        oped   *s;   
        char   ch,op;   
        int   sum=0,temp,a,b;   
        init_optr(p);push_optr(p,'#');   
        init_oped(s);   
        printf("\nplease   enter   :");   
        ch=getchar();   
        while(ch!='#'||(op=gettop(p))!='#')   
          {if(ch>='0'&&ch<='9')   
                {sum=sum*10+(ch-'0');ch=getchar();}   
            else   {push_oped(s,sum);   
        sum=0;   
        
            A1:       switch   (precede(gettop(p),ch))   
        {case   '<':push_optr(p,ch);ch=getchar();break;   
          case   '=':if(ch=='#')   break;   
            else   {pop_optr(p);   
        ch=getchar();   
        break;}   
          case   '>':{b=pop_oped(s);op=pop_optr(p);a=pop_oped(s);   
              temp=operate(a,op,b);   
              push_oped(s,temp);   
              goto   A1;   
              }   
        }   
        }   
            }   
          printf("\ncomeout:%d",pop_oped(s));   
        }
      

  3.   

    // SuperCalc.cs - 超级计算器using System;
    using System.Windows.Forms;
    using System.CodeDom.Compiler;
    using Microsoft.VisualBasic;
    using System.Reflection;
    using System.Text;
    using System.Globalization;namespace Skyiv
    {
      class SuperCalc : Form
      {
        TextBox tbxA1;
        TextBox tbxA3;    [STAThread]
        static void Main(string [] args)
        {
          Application.Run(new SuperCalc());
        }    SuperCalc()
        {
          Text              = "Super Calculator";
          StartPosition     = FormStartPosition.CenterScreen;
          Width             = 300;
          Height            = 300;      tbxA1             = new TextBox();
          tbxA1.Parent      = this;
          tbxA1.Multiline   = true;
          tbxA1.WordWrap    = false;
          tbxA1.Dock        = DockStyle.Fill;
          tbxA1.BorderStyle = BorderStyle.FixedSingle;      Panel pnlA1       = new Panel();
          pnlA1.Parent      = this;
          pnlA1.Height      = 22;
          pnlA1.Dock        = DockStyle.Top;      tbxA3             = new TextBox();
          tbxA3.Parent      = pnlA1;
          tbxA3.Dock        = DockStyle.Fill;
          tbxA3.BorderStyle = BorderStyle.FixedSingle;
          tbxA3.ReadOnly    = true;      Button btnA3      = new Button();
          btnA3.Text        = "&Calculate";
          btnA3.Parent      = pnlA1;
          btnA3.Width       = 80;
          btnA3.Dock        = DockStyle.Left;
          btnA3.Click      += new EventHandler(Calc_Clicked);
        }    void Calc_Clicked(object sender, EventArgs ea)
        {
          (sender as Control).Enabled = false;
          try
          {
            tbxA3.Text = (new Expression(tbxA1.Text)).Compute().ToString();
          }
          catch (Exception ex)
          {
            MessageBox.Show(ex.Message, "Error");
          }
          finally
          {
            (sender as Control).Enabled = true;
          }
        }
      }
      // VBExpression.cs - 动态生成数学表达式并计算其值
      // 表达式使用 Visual Baisc 语法
      // 可使用 pi、e 等常量,sin、cos、tan、log、sqrt 等函数  sealed class Expression
      {
        object instance;
        MethodInfo method;    public Expression(string expression)
        {
          if (expression.ToUpper(CultureInfo.InvariantCulture).IndexOf("RETURN") < 0)
          {
            expression = "Return " + expression.Replace(Environment.NewLine, " ");
          }
          string className = "Expression";
          string methodName = "Compute";
          CompilerParameters p = new CompilerParameters();
          p.GenerateInMemory = true;
          CompilerResults cr = new VBCodeProvider().CompileAssemblyFromSource
          (
            p,
            string.Format
            (
              @"Option Explicit Off
              Option Strict Off
              Imports System, System.Math, Microsoft.VisualBasic
              NotInheritable Class {0}
              Public Function {1} As Double
              {2}
              End Function
              End Class",
              className, methodName, expression
            )
          );
          if(cr.Errors.Count > 0)
          {
            string msg = "Expression(\"" + expression + "\"): \n";
            foreach (CompilerError err in cr.Errors) msg += err.ToString() + "\n";
            throw new Exception(msg);
          }
          instance = cr.CompiledAssembly.CreateInstance(className);
          method = instance.GetType().GetMethod(methodName);
        }    public double Compute()
        {
          return (double)method.Invoke(instance, null);
        }
      }
    }
      

  4.   

    http://www.google.com/search?q=4*36%2B7%2B88%2F12%5E2&hl=zh-CN&newwindow=1&lr=&nxpt=20.39471539279207923300 (4 * 36) + 7 + (88 / (12^2)) = 151.611111
      

  5.   

    难道net框架里就没有解决这个问题的类?
      

  6.   


    果然是无敌方法!!!——在效率方面:DataTable 的 Compute()  在计算时:速度特别快!——基本的加减法几乎不消耗时间楼主的:
    Expression 的 Compute()  在计算时:速度都保持在 300 毫秒 左右!——基本的加减法也消耗这么多的时间:估计是在 编译时浪费了时间;——但是,不容否认:Expression  真的很无敌.....