C# 如何 处理四则运算

时间:2022-04-23 20:39:34
就是数学中的四则运算
如:1+2*(3+4*5)/6-7=?

也就是运算表达式没有固定的格式
我要写一个类去处理它们 ,然后直接输出结果
有没有有效的方法》?

27 个解决方案

#1


??????????

#2


有点复杂,20分太少了。。。

首先,括号需要从最右左括号开始解括号;
然后,算法的优先级结合
然后,计算

#3


这个要考验你的程序功底了。
从左到右一个字符一个字符的读吧。
根据字符不同,确定不同的处理方式。
如果是数字,用变量记录下,如果是运算符判断计算方式。
还有括号,很麻烦,还有计算的优先级等。。。

#4


双堆栈(操作符栈,操作数栈)+ 符号优先级表,数据结构和编译都涉及这个问题

#5


分数是如此至少,解决起来如此复杂

#6


引用 4 楼 ivorstar 的回复:
双堆栈(操作符栈,操作数栈)+ 符号优先级表,数据结构和编译都涉及这个问题

老兄 你的意思是不是跟这个有点像?
http://bloodwolf-china.javaeye.com/blog/472070

#7


引用 6 楼 zhehan54 的回复:
引用 4 楼 ivorstar 的回复:
双堆栈(操作符栈,操作数栈)+ 符号优先级表,数据结构和编译都涉及这个问题

老兄 你的意思是不是跟这个有点像?
http://bloodwolf-china.javaeye.com/blog/472070


就是这个意思……

#8


DataTable.Compute("1+2*(3+4*5)/6-7")

javascript:var v=eval("1+2*(3+4*5)/6-7");

#9


//教你一个最简单的方法,用动态类实现,
//并且效率非常好,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;
namespace CalStringValue
{
    class Program
    {
        public static double Function(string str)
        {
            double result;
            
            StringBuilder classBody = new StringBuilder(400);
            classBody.AppendLine("using System;");
            classBody.AppendLine("public class TempClass");
            classBody.AppendLine("{");
            classBody.AppendLine("public double Fun()");
            classBody.AppendLine("{");
            classBody.AppendLine(string.Format(" return {0};",str));
            classBody.AppendLine("}");
            classBody.AppendLine("}");

            CSharpCodeProvider provider = new CSharpCodeProvider();
            CompilerParameters cp = new CompilerParameters();
            cp.GenerateExecutable = false;
            cp.GenerateInMemory = true;
            CompilerResults compResult = provider.CompileAssemblyFromSource(cp, classBody.ToString());
            object   obj = compResult.CompiledAssembly.CreateInstance("TempClass");
            Type objType=obj.GetType();          
                MethodInfo method = objType.GetMethod("Fun");
               result=Convert.ToDouble(method.Invoke(obj, null));
               return result;



        }
        static void Main(string[] args)
        {
            string str = "";
            do
            {
                Console.WriteLine("Input expression:(-1 to Exit)");
                str = Console.ReadLine();

                try
                {
                    Console.WriteLine("the result is:{0}", Function(str));
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            } while (str != "-1");
        }
    }
}

#10


object obj=new DataTable().Compute("1+3*4/4",null")

#11


敲错了,是
object obj=new DataTable().Compute("1+3*4/4",null);

#12


引用 8 楼 lost_painting 的回复:
DataTable.Compute("1+2*(3+4*5)/6-7")

javascript:var v=eval("1+2*(3+4*5)/6-7");

DataTable.Compute 表达式内似乎用不了 中括号

#13


引用 11 楼 aimeast 的回复:
敲错了,是

C# code
object obj=new DataTable().Compute("1+3*4/4",null);


DataTable().Compute() 似乎用不了中括号 

#14


引用 11 楼 aimeast 的回复:
敲错了,是

C# code
object obj=new DataTable().Compute("1+3*4/4",null);


DataTable().Compute() 似乎用不了中括号 

#15


为什么要用中括号?
程序中因为括号中可能不断增加下去, 所以全是小括号。

#16


引用 14 楼 zhehan54 的回复:
引用 11 楼 aimeast 的回复:
敲错了,是

C# code
object obj=new DataTable().Compute("1+3*4/4",null);


DataTable().Compute() 似乎用不了中括号


都换成小括号吧

#17


引用 15 楼 cjcgy 的回复:
为什么要用中括号?
程序中因为括号中可能不断增加下去, 所以全是小括号。


老兄 你说的我不懂
为什么不可以用中括号?
程序中因为括号中可能不断增加下去 到底是什么意思 ?

#18


逆波兰式

如果你学过数据结构和编译原理多好啊。

#19


//先项目右键中添加Microsoft.JScript引用
            Microsoft.JScript.GlobalObject.eval("1+2");

#20


怎么还要用类啊

#21


Math.Round(3.44, 1) = 3.4

#22


你要是想计算{[(1+2)*3+4]*5+6}*7的结果,只需要计算(((1+2)*3+4)*5+6)*7。
即把所有的“[”“{”替换为“)”,把所有的“]”“}”替换为“)”。

这样难道不行吗?

#23


一直都渴望用C来实现,一直都知难而退!

#24


引用 23 楼 cbsoftlover 的回复:
一直都渴望用C来实现,一直都知难而退!
用栈,很简单的。

#25


我上几周才实现了一个,用的是表达式树的思路,当然教科书上也应有类似的思路,我觉得肯定早就有人想过我的这种思路了,有知道的大侠请指出来(好像就是逆波兰计算公式?):

1.在四则运算中,一个表达式分为 操作结果Result、操作符Opt、操作数Opd三部分
2.一个操作符Opt带两个操作数Opd 
3.一个表达式可以表示为 Result = Opd1 Opt Opd2
4.操作结果Result也可以作为另一个表达式的操作数
5.于是一个四则运算的表达式就可以用表达式树(计算时使用递归,看起来更像是堆栈)的形式来表示

1+2*(3+4*5)/6-7=?
4*5
   +3
     *2
       /6
         +1
           -7

<Result>R
<Opt symbol="-">
<Opt symbol="+">
<Opt symbol="/">
<Opt symbol="*">
<Opd>2</Opd>
<Opt symbol="+">
<Opt symbol="*">
<Opd>5</Opd>
<Opd>4</Opd>
</Opt>
<Opd>3</Opd>
</Opt>
</Opt>
<Opd>6</Opd>
</Opt>
<Opd>1</Opd>
</Opt>
<Opd>7</Opd>
</Opt>
</Result>


能把表达式分析为上面的形式,就不难用递归去计算结果了。

#26


该回复于2012-04-15 20:51:43被版主删除

#27


谁有C#窗体应用程序的源码啊  包括加减乘法的  

#1


??????????

#2


有点复杂,20分太少了。。。

首先,括号需要从最右左括号开始解括号;
然后,算法的优先级结合
然后,计算

#3


这个要考验你的程序功底了。
从左到右一个字符一个字符的读吧。
根据字符不同,确定不同的处理方式。
如果是数字,用变量记录下,如果是运算符判断计算方式。
还有括号,很麻烦,还有计算的优先级等。。。

#4


双堆栈(操作符栈,操作数栈)+ 符号优先级表,数据结构和编译都涉及这个问题

#5


分数是如此至少,解决起来如此复杂

#6


引用 4 楼 ivorstar 的回复:
双堆栈(操作符栈,操作数栈)+ 符号优先级表,数据结构和编译都涉及这个问题

老兄 你的意思是不是跟这个有点像?
http://bloodwolf-china.javaeye.com/blog/472070

#7


引用 6 楼 zhehan54 的回复:
引用 4 楼 ivorstar 的回复:
双堆栈(操作符栈,操作数栈)+ 符号优先级表,数据结构和编译都涉及这个问题

老兄 你的意思是不是跟这个有点像?
http://bloodwolf-china.javaeye.com/blog/472070


就是这个意思……

#8


DataTable.Compute("1+2*(3+4*5)/6-7")

javascript:var v=eval("1+2*(3+4*5)/6-7");

#9


//教你一个最简单的方法,用动态类实现,
//并且效率非常好,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;
namespace CalStringValue
{
    class Program
    {
        public static double Function(string str)
        {
            double result;
            
            StringBuilder classBody = new StringBuilder(400);
            classBody.AppendLine("using System;");
            classBody.AppendLine("public class TempClass");
            classBody.AppendLine("{");
            classBody.AppendLine("public double Fun()");
            classBody.AppendLine("{");
            classBody.AppendLine(string.Format(" return {0};",str));
            classBody.AppendLine("}");
            classBody.AppendLine("}");

            CSharpCodeProvider provider = new CSharpCodeProvider();
            CompilerParameters cp = new CompilerParameters();
            cp.GenerateExecutable = false;
            cp.GenerateInMemory = true;
            CompilerResults compResult = provider.CompileAssemblyFromSource(cp, classBody.ToString());
            object   obj = compResult.CompiledAssembly.CreateInstance("TempClass");
            Type objType=obj.GetType();          
                MethodInfo method = objType.GetMethod("Fun");
               result=Convert.ToDouble(method.Invoke(obj, null));
               return result;



        }
        static void Main(string[] args)
        {
            string str = "";
            do
            {
                Console.WriteLine("Input expression:(-1 to Exit)");
                str = Console.ReadLine();

                try
                {
                    Console.WriteLine("the result is:{0}", Function(str));
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            } while (str != "-1");
        }
    }
}

#10


object obj=new DataTable().Compute("1+3*4/4",null")

#11


敲错了,是
object obj=new DataTable().Compute("1+3*4/4",null);

#12


引用 8 楼 lost_painting 的回复:
DataTable.Compute("1+2*(3+4*5)/6-7")

javascript:var v=eval("1+2*(3+4*5)/6-7");

DataTable.Compute 表达式内似乎用不了 中括号

#13


引用 11 楼 aimeast 的回复:
敲错了,是

C# code
object obj=new DataTable().Compute("1+3*4/4",null);


DataTable().Compute() 似乎用不了中括号 

#14


引用 11 楼 aimeast 的回复:
敲错了,是

C# code
object obj=new DataTable().Compute("1+3*4/4",null);


DataTable().Compute() 似乎用不了中括号 

#15


为什么要用中括号?
程序中因为括号中可能不断增加下去, 所以全是小括号。

#16


引用 14 楼 zhehan54 的回复:
引用 11 楼 aimeast 的回复:
敲错了,是

C# code
object obj=new DataTable().Compute("1+3*4/4",null);


DataTable().Compute() 似乎用不了中括号


都换成小括号吧

#17


引用 15 楼 cjcgy 的回复:
为什么要用中括号?
程序中因为括号中可能不断增加下去, 所以全是小括号。


老兄 你说的我不懂
为什么不可以用中括号?
程序中因为括号中可能不断增加下去 到底是什么意思 ?

#18


逆波兰式

如果你学过数据结构和编译原理多好啊。

#19


//先项目右键中添加Microsoft.JScript引用
            Microsoft.JScript.GlobalObject.eval("1+2");

#20


怎么还要用类啊

#21


Math.Round(3.44, 1) = 3.4

#22


你要是想计算{[(1+2)*3+4]*5+6}*7的结果,只需要计算(((1+2)*3+4)*5+6)*7。
即把所有的“[”“{”替换为“)”,把所有的“]”“}”替换为“)”。

这样难道不行吗?

#23


一直都渴望用C来实现,一直都知难而退!

#24


引用 23 楼 cbsoftlover 的回复:
一直都渴望用C来实现,一直都知难而退!
用栈,很简单的。

#25


我上几周才实现了一个,用的是表达式树的思路,当然教科书上也应有类似的思路,我觉得肯定早就有人想过我的这种思路了,有知道的大侠请指出来(好像就是逆波兰计算公式?):

1.在四则运算中,一个表达式分为 操作结果Result、操作符Opt、操作数Opd三部分
2.一个操作符Opt带两个操作数Opd 
3.一个表达式可以表示为 Result = Opd1 Opt Opd2
4.操作结果Result也可以作为另一个表达式的操作数
5.于是一个四则运算的表达式就可以用表达式树(计算时使用递归,看起来更像是堆栈)的形式来表示

1+2*(3+4*5)/6-7=?
4*5
   +3
     *2
       /6
         +1
           -7

<Result>R
<Opt symbol="-">
<Opt symbol="+">
<Opt symbol="/">
<Opt symbol="*">
<Opd>2</Opd>
<Opt symbol="+">
<Opt symbol="*">
<Opd>5</Opd>
<Opd>4</Opd>
</Opt>
<Opd>3</Opd>
</Opt>
</Opt>
<Opd>6</Opd>
</Opt>
<Opd>1</Opd>
</Opt>
<Opd>7</Opd>
</Opt>
</Result>


能把表达式分析为上面的形式,就不难用递归去计算结果了。

#26


该回复于2012-04-15 20:51:43被版主删除

#27


谁有C#窗体应用程序的源码啊  包括加减乘法的