陆陆续续更新这个计算器用了一个礼拜了,今天无论如何也要把它更完。笔者有点追求完美,再者每天都有课,晚上还有作业,还有每晚都会写一些其他的博文。

  上一次漏了写如何实现计算的。思路如下:

  之前得到一个栈2stack2,里面存的是逆波兰式。但是注意了,式子是反过来的。因为栈只能从栈顶写入,从栈顶拿出。所以,必须把栈2的数反过来。

  下面是转换的代码:

        //
//将栈2数值倒过来
//
private void UpSideDown()
{
string[] strTemp = stack2.ToArray(); //将栈stack2数值临时存储在数组里
stack2.Clear(); //将栈stack2清空
for(int i=strTemp.Length-;i>=;i--)
{
stack2.Push(strTemp[i]);
}
}

  将栈的数值倒过来之后,我们就可以进行计算了,计算的思路如下:按下图步骤

  1:从栈顶取元素,如果是数字直接存入新栈 2:如果是操作符,则不存入,将新栈的前两个元素依次取出,先取出的数字放在运算符右边,后取出的放在左边 3:计算的结果放回新栈。重复以上步骤,知道计算完。

  注意!新栈保存的数字,所以要注意栈的类型。

        //
//计算四则运算
//
public double DoMath()
{
var stackTemp = new Stack<double>();
try
{
while (myStack2.Count != )
{
if (!IfNumber(myStack2.Peek()))
{
double d1 = stackTemp.Pop();
double d2 = stackTemp.Pop();
switch (myStack2.Pop())
{
case "+":
stackTemp.Push(d2 + d1);
break;
case "-":
stackTemp.Push(d2 - d1);
break;
case "*":
stackTemp.Push(d2 * d1);
break;
case "/":
stackTemp.Push(d2 / d1);
break;
}//end switch
}//end if
else
{
stackTemp.Push(Convert.ToDouble(myStack2.Pop()));
}
}//end while
return stackTemp.Pop();
}
catch
{
return ;
}
}

  四则混合运算的大体步骤和解决思路就这么多,现在开始解决如何确保用户在乱输入公式以及得到的公式该怎么解析(前面提到的问题:就是当接受了加括号的一元运算符比如:1+(-2)。转换得到的式子是不能正确计算的。)

  思路一:怎么解决用户乱输入数字

  用栈保存用户每次按的按键内容,除了第一次输入外,在每次输入的时候与栈顶元素进行比较。如果连续两次输入操作符,则视第二次有效:

        private string str = "";                                    //声明切定义一个空字符串,用于在label显示用户输入
Stack<string> tempStack = new Stack<string>(); //声明一个数组,用去存储用户输入 //判断用户点击是否有效
public void IfValid(string s)
{
if (tempStack != null)
{
if (Calculate.IfNumber(s)) //如果用户按得是数字,则输入有效
{
tempStack.Push(s);
}
else
{
if (!Calculate.IfNumber(tempStack.Peek())) //如果用户连续两次按的是操作符,则视第二次有效
{
tempStack.Pop();
tempStack.Push(s);
}
else
tempStack.Push(s);
} }//end if
else
{
tempStack.Push(s);
}
str = "";
string[] tempStr = tempStack.ToArray();
//将得到的数组反转
for (int i = ; i < tempStr.Length / ; i++)
{
string temp = tempStr[i];
tempStr[i] = tempStr[tempStr.Length - i - ];
tempStr[tempStr.Length - i - ] = temp;
}
foreach (var item in tempStr)
str += item;
label1.Text = str; }
private void button1_Click(object sender, EventArgs e)
{
IfValid(button1.Text);
} private void button2_Click(object sender, EventArgs e)
{
IfValid(button2.Text);
}

  笔者有很多地方都用到将数组元素前后倒过来的代码,但却没有将其写成独立函数,造成代码的冗余。

  这里代码是写在Form1里的,用到了ReversePolish的IsNumber的方法,因为是不同类的,而且没有ReversePolish就直接调用,所以要把之前定义的修饰private 改成public static修饰才能直接调用。

  思路二:当接受了加括号的一元运算符比如:1+(-2)。通过逆波兰法则转换得到的式子是不能正确计算的。

  把式子进行解析,写成:1+(0-2)的形式!

  代码如下:

  

       string[] strAnalysis;                                           //存放解析完原始计算公式之后的公式
string[] str; //string数组str用于存放原始计算公式//
//解析原始计算公式
//
public void Analysis()
{
var stackTemp = new Stack<string>(); int count = ;
try
{
while (count < strAnalysis.Length)
{
if (strAnalysis[count] == "(" && (strAnalysis[count + ] == "-" || strAnalysis[count + ] == "+")) //如果公式操作数(的后一位操作数是+或则-,
{
stackTemp.Push(strAnalysis[count]);
stackTemp.Push("");
count++;
}
else if (!IfNumber(strAnalysis[count]))
{
stackTemp.Push(strAnalysis[count]);
count++;
}
else if (IfNumber(strAnalysis[count]))
{
string strTemp = "";
while (count < strAnalysis.Length && IfNumber(strAnalysis[count])) //如果是数字,包括小数点.,则拼成一个字符串,直到遇到一个操作符或则数组遍历完毕
{
strTemp += strAnalysis[count];
count++;
}
stackTemp.Push(strTemp);
}
}
}
catch
{
stackTemp = null;
} str = stackTemp.ToArray();
//反转字符串数组
for (int i = ; i < str.Length / ; i++)
{
string temp = str[i];
str[i] = str[str.Length - i - ];
str[str.Length - i - ] = temp;
}
}

  大体思路思路就这么多了,总之是问题逐一突破,把解决的问题方案写成方法,最后凑在一起就成功了。以上的代码并不是所有的代码,笔者只是想把自己的思路分享一下。因为我猜如果我把所有代码都贴出来是要花很长时间看的。毕竟每个人的思维不一样。本人就不擅长读别人的代码T T。

  提示:一般遇到访问内存,比如取栈压栈访问栈顶的代码,最好上异常处理,因为很容易就出现错误。

  欢迎大家提出质疑!

Windows Form简易计算器实现(下)的更多相关文章

  1. C#Windows Form简易计算器实现(上)

    第一次写博客,来分享一个简易计算器的代码.作为一名准程序员,就是要多写代码才能孰能生巧.重视基础知识才能飞的更快更高以及更稳. 代码可能会写的很糟糕,不完美不安全之处希望发现的越多越好 c#编写计算器 ...

  2. C#Windows Form简易计算器实现(中)

    昨天花了一天的时间弄计算器.也算是做出来了,还是简易的(怀疑猿生!!).在此先感谢昨天被我骚扰的朋友. 先贴一张界面看看 其实健壮性还是挺差的,用户体验也是极差的.比如说用户输入了不合理运算式子,我就 ...

  3. 自制c#简易计算器

    这是一个课堂作业,我觉得作为一个简易的计算器不需要态度复杂的东西,可能还有一些bug,有空再慢慢加强. using System;using System.Collections.Generic;us ...

  4. JavaScript简易计算器

    JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标 ...

  5. Windows Form 中快捷键设置

    在Windows Form程序中使用带下划线的快捷键只需要进行设置: 就能够工作.

  6. VS2008 Windows Form项目安装包生成详解

    2008 Windows Form项目的发布对有经验的程序员来说,可能不值一提,但对很多新手来说却不知道如何操作,因为在很多关于Visual Studio的书籍中也没有相关介绍,权威如<C# 2 ...

  7. VISUAL STUDIO 2008 WINDOWS FORM项目发布生成安装包详解(转)

    转自:http://www.cnblogs.com/killerofyang/archive/2012/05/31/2529193.html Visual Studio 2008 Windows Fo ...

  8. PHP学习笔记02——简易计算器

    <!DOCTYPE html> <html> <head> <title>PHP简易计算器</title> </head> &l ...

  9. 菜鸟学习Struts——简易计算器

    这是学习Struts的一个简单的例子文件结构如下: 1.配置Struts环境 2.新建input.jsp,success.jsp,error.jsp input.jsp代码如下: <%@ pag ...

随机推荐

  1. leetcode第23题--Swap Nodes in Pairs

    Problem: Given a linked list, swap every two adjacent nodes and return its head. For example,Given 1 ...

  2. JTAG应该如何接线

    下面是某个ARM9评估板的原理图: 注意: 1. Vref和Vtarget可以直接连在一起,由被调试板提供3.3V或5V电源: 2. nTRST,最好上拉: 3. TDI,最好上拉 4. TMS,最好 ...

  3. Plugin For KanColleViewer – Provissy Tools V1.0

    これはKanColleViewerためのプラグインです,KanColleViewerの機能を拡張する. #介绍 / Introduction / 紹介这是一个KanColleViewer(俗称”提督很 ...

  4. SQL远程恢复

    原文:SQL远程恢复 -- ============================================= -- Author: dcrenl -- Create date: 2013-9 ...

  5. android application简要类(一)

    每次应用程序执行.应用application保持实例化的阶级地位.推而广之applicaiton类别,能够完成以下3长期工作: 1.至android应用级事件,如广播的实现中低声回应. 2.传递应用程 ...

  6. 【jar包】JSON之解析利器GSON--【gson-2.2.4.jar】

    Gson(又称Google Gson)是Google公司发布的一个开放源代码的Java库,主要用途为串行化Java对象为JSON字符串,或反串行化JSON字符串成Java对象.GSON核心jar包不到 ...

  7. Moon.Orm 5.0 (MQL版)

    Moon.Orm 5.0 (MQL版) 实战实例Moon.Orm 5.0 革命性的设计 打造最便捷的异步分页技术(提供下载) 摘要: 一.建一个项目(以WebForm为例)配置文件配置(注意您自己的路 ...

  8. 深入剖析Provider Model

    Membership三步曲之进阶篇 - 深入剖析Provider Model Membership 三步曲之进阶篇 - 深入剖析Provider Model 本文的目标是让每一个人都知道Provide ...

  9. greenlet微线程

    Greenlet简介 一个 “greenlet” 是一个很小的独立微线程.可以把它想像成一个堆栈帧,栈底是初始调用,而栈顶是当前greenlet的暂停位置.你使用greenlet创建一堆这样的堆 栈, ...

  10. GMap.Net

    GMap.Net开发之在WinForm和WPF中使用GMap.Net地图插件   GMap.NET是什么? 来看看它的官方说明:GMap.NET is great and Powerful, Free ...