黑马程序员技术交流社区

标题: 怎么实现计算器中的连续运算的功能 [打印本页]

作者: 姐的霸气谁懂    时间: 2013-10-20 14:04
标题: 怎么实现计算器中的连续运算的功能
本帖最后由 姐的霸气谁懂 于 2013-10-22 18:21 编辑

琢磨了挺久 发现实现计算器连续运算的功能还是没有头绪 哪位大神出来帮帮忙啊
作者: 王云峰    时间: 2013-10-20 17:17
你只用一个textbox,想想真实的计算器,在你得到第一次运算结果之后,直接按运算符,你就把上次运算的结果当作输入的第一个数字,按运算符之后再输入一个数字进行运算,这不就连续运算了吗?
作者: 荣右铭    时间: 2013-10-20 17:39
我最近也在研究这个问题,假设用户输入了一个算式是这样的:
4+5-7*2
类似的长算式,怎么让程序连续计算呢,首先第一步是要把这个串调整成后缀表达式的形式,就是所有数字在前而运算符在后面倒序排列的形式,拿刚才那个算式来说,就是变成这样:
4,5,7,2,*,-,+
这时候你会发现算式和运算符分成了两组(可以装到两个栈里),然后开始运算,运算的过程是这样的:
数字栈中弹出一个数2
操作数栈弹出一个运算符*
数字栈再弹出一个数7
运算,将结果压回数字栈中
重复 弹出数字,弹出运算符 再弹出数字,运算,结果压入栈 这个操作
最后很让人头疼的一个问题是运算符的优先级,当*和+运算在一起时,或者先减后加时,你需要调整运算的顺序,如何调整,见仁见智
另外别忘了在任何需要的时候处理异常,还有检查用户的输入是否合法
代码我只给出调整为后缀表达式的方法,其他的你自己思考吧,权贴出来代码就太长了,这里仅仅给你提供一种思路。
string str = Console.ReadLine();
            //接受用户输入的一个串
            string[] str2 = new string[64];
            //声明一个储存数字的字符串数组
            char[] op = new char[4] { '+', '-', '*', '/' };
            //声明一个包含四种运算符的字符数组
            char[] op2 = new char[64];
            //声明一个储存算式中出现的运算符(有顺序)的字符数组
            str2 = str.Split(op);
            //将输入串按照运算符的间隔分割成各个数字(需要转换成int)
            for (int i = 0; i < str.Length; i++)
            {//检索字符串中出现的运算符,倒序存入运算符数组中
                switch (str.Substring(str.Length - i - 1, 1))
                {
                    case "+":
                        op2[i] = '+';
                        break;
                    case "-":
                        op2[i] = '-';
                        break;
                    case "*":
                        op2[i] = '*';
                        break;
                    case "/":
                        op2[i] = '/';
                        break;
                    default:
                        break;
                }

            }
作者: 荣右铭    时间: 2013-10-20 18:02
王云峰 发表于 2013-10-20 17:17
你只用一个textbox,想想真实的计算器,在你得到第一次运算结果之后,直接按运算符,你就把上次运算的结果 ...

优先级的问题怎么解决?
如果用户按了3、加号、5、乘号 、7
那最后肯定是要先运算5*7,而不是3+5,还有括号的问题,不能指望着用户自己调整优先级,无论是winform版的还是控制台版的,都得考虑这个问题
作者: 夏闯富    时间: 2013-10-20 18:06
本帖最后由 夏闯富 于 2013-10-20 18:07 编辑

我用的是委托,下面是全部后台代码(用wpf做的)
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Data;
  8. using System.Windows.Documents;
  9. using System.Windows.Input;
  10. using System.Windows.Media;
  11. using System.Windows.Media.Imaging;
  12. using System.Windows.Navigation;
  13. using System.Windows.Shapes;

  14. namespace 计算器
  15. {
  16.     /// <summary>
  17.     /// MainWindow.xaml 的交互逻辑
  18.     /// </summary>
  19.     public delegate int 委托(int F, int S);
  20.     public partial class MainWindow : Window
  21.     {
  22.         委托 a;
  23.         int f;
  24.         
  25.         public MainWindow()
  26.         {
  27.             InitializeComponent();
  28.         }

  29.         private void _7_Click(object sender, RoutedEventArgs e)
  30.         {
  31.             
  32.             Button button = (Button)sender;
  33.             btn.Content = button.Content;
  34.             

  35.         }

  36.         private void Button_Click_1(object sender, RoutedEventArgs e)
  37.         {
  38.             a = new 委托(运算方法.加法);
  39.             f = Convert.ToInt32(btn.Content);
  40.         }

  41.         private void Button_Click_2(object sender, RoutedEventArgs e)
  42.         {
  43.             a = new 委托(运算方法.减法);
  44.             f = Convert.ToInt32(btn.Content);
  45.         }

  46.         private void Button_Click_3(object sender, RoutedEventArgs e)
  47.         {
  48.             a = new 委托(运算方法.乘法);
  49.             f = Convert.ToInt32(btn.Content);
  50.         }

  51.         private void Button_Click_4(object sender, RoutedEventArgs e)
  52.         {
  53.             a = new 委托(运算方法.除法);
  54.             f = Convert.ToInt32(btn.Content);
  55.         }

  56.         private void Result(object sender, RoutedEventArgs e)
  57.         {
  58.            int R= a(f,Convert.ToInt32( btn.Content));
  59.            btn.Content = R.ToString();
  60.         }
  61.     }
  62.    public static class 运算方法
  63.     {

  64.        static public int 加法(int F,int S )
  65.         {
  66.            return F + S;
  67.         }
  68.        static public int 减法(int F, int S)
  69.         {
  70.             return F - S;
  71.         }
  72.        static public int 乘法(int F, int S)
  73.         {
  74.             return F * S;
  75.         }
  76.        static public int 除法(int F, int S)
  77.         {
  78.             return F / S;
  79.         }
  80.    
  81.    
  82.     }
  83. }
复制代码

作者: 荣右铭    时间: 2013-10-20 18:15
夏闯富 发表于 2013-10-20 18:06
我用的是委托,下面是全部后台代码(用wpf做的)

别忘了处理除0异常
作者: 夏闯富    时间: 2013-10-20 18:16
本帖最后由 夏闯富 于 2013-10-20 18:19 编辑

这是我模仿Window计算器做的项目
里面只是简单的计算,没有处理0引发的异常
只做了Int类型的。
连加貌似也没做。。。
有兴趣的可以完善一下

计算器.zip

373.94 KB, 下载次数: 133


作者: 追溯客    时间: 2013-10-20 18:32
楼主你好,如果您的问题得到解决,请及时把分类设为已解决,黑马有你更精彩!

作者: 夏闯富    时间: 2013-10-20 18:38
刚刚想了一下思路:连加
每次按“+”号时就把前面输入的数结果算出来,但不显示, 按“=”再把之前算的结果再加上前一次输入的值相加并显示。
比如:
求1+2+3的值
默认第一个值是0,先按1再按“+”,按“+”这个按钮时触发0+1=1,这里先不显示结果(按等于号才是显示结果)。
再按2再按“+”,按“+”这个按钮时触发1(是0+1的结果)+2=3,
再按3,再按等于“=“触发3(这是1+2的结果)+3=6,并显示出来


作者: 782385854    时间: 2013-10-20 19:10
可以分步骤进行运算,先加完后储存下值,用这个值进行下一个运算,全部写出来后运算加括号,
作者: 茹化肖    时间: 2013-10-21 17:14
关于连续计算的问题在数据结构中 关于栈的部分有解释哦。我现在手边没有那本书 不能具体给你找找。
作者: 追溯客    时间: 2013-10-25 11:08
同学给你加分了!好好学习!蔡蔡和叶叶在黑马等着你!黑马有你更精彩!快点为了当土豪努力吧!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2