Windows Form简易计算器实现(下)
陆陆续续更新这个计算器用了一个礼拜了,今天无论如何也要把它更完。笔者有点追求完美,再者每天都有课,晚上还有作业,还有每晚都会写一些其他的博文。
上一次漏了写如何实现计算的。思路如下:
之前得到一个栈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简易计算器实现(下)的更多相关文章
- C#Windows Form简易计算器实现(上)
第一次写博客,来分享一个简易计算器的代码.作为一名准程序员,就是要多写代码才能孰能生巧.重视基础知识才能飞的更快更高以及更稳. 代码可能会写的很糟糕,不完美不安全之处希望发现的越多越好 c#编写计算器 ...
- C#Windows Form简易计算器实现(中)
昨天花了一天的时间弄计算器.也算是做出来了,还是简易的(怀疑猿生!!).在此先感谢昨天被我骚扰的朋友. 先贴一张界面看看 其实健壮性还是挺差的,用户体验也是极差的.比如说用户输入了不合理运算式子,我就 ...
- 自制c#简易计算器
这是一个课堂作业,我觉得作为一个简易的计算器不需要态度复杂的东西,可能还有一些bug,有空再慢慢加强. using System;using System.Collections.Generic;us ...
- JavaScript简易计算器
JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标 ...
- Windows Form 中快捷键设置
在Windows Form程序中使用带下划线的快捷键只需要进行设置: 就能够工作.
- VS2008 Windows Form项目安装包生成详解
2008 Windows Form项目的发布对有经验的程序员来说,可能不值一提,但对很多新手来说却不知道如何操作,因为在很多关于Visual Studio的书籍中也没有相关介绍,权威如<C# 2 ...
- VISUAL STUDIO 2008 WINDOWS FORM项目发布生成安装包详解(转)
转自:http://www.cnblogs.com/killerofyang/archive/2012/05/31/2529193.html Visual Studio 2008 Windows Fo ...
- PHP学习笔记02——简易计算器
<!DOCTYPE html> <html> <head> <title>PHP简易计算器</title> </head> &l ...
- 菜鸟学习Struts——简易计算器
这是学习Struts的一个简单的例子文件结构如下: 1.配置Struts环境 2.新建input.jsp,success.jsp,error.jsp input.jsp代码如下: <%@ pag ...
随机推荐
- 成C++应用程序世界------异常处理
一. 概述 C++自身有着很强的纠错能力,发展到现在,已经建立了比較完好的异常处理机制.C++的异常情况无非两种,一种是语法错误,即程序中出现了错误的语句,函数,结构和类,致使编译程序无法进行.还有一 ...
- 必须掌握的JavaScript基本知识
作为一个前端工作者,应该了解一些javascript的发展历史,javascript实现及版本等.基本概念包括语法.关键字.变量.数据类型.操作符.语句控制及函数等,它们和我们学习的其它语言C/C++ ...
- NET开发面向对象2
面向对象 (2) 继续上一篇<ASP.NET开发,从二层至三层,至面向对象>http://www.cnblogs.com/insus/p/3822624.html .我们了解到怎样把自己的 ...
- 使用 ArcGIS Online和APP进行监控操作和数据采集
主要介绍的App是Operations Dashboard for ArcGIS 和 Collector for ArcGIS,它们 提高了组织内日常操作的效率.精度和响应速度. 已经购买了 ArcG ...
- Objective-c 总结(一):OC类的设计
(一)学习目标: 1.面向对象基本概念: OOP的主要思想是把构成问题的各个事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描述一个事物在整个解决问题步骤中的行为. 2.熟悉OC类的定 ...
- treeview和listview的用法
今天无聊中弄了个小东西,熟悉一下对listview和treeview的用法.代码如下: public partial class Form1 : Form { private ...
- [原]Escape From the iOS Sanbox on Jailbreak Device
just my thinking, 3 ways to escape from sandbox on jailbreak device, to do file copying or execute s ...
- [转]Native Java Bytecode Debugging without Source Code
link from:http://www.crowdstrike.com/blog/native-java-bytecode-debugging-without-source-code/index.h ...
- JAVA算法两道
算法(JAVA)----两道小小课后题 LZ最近翻了翻JAVA版的数据结构与算法,无聊之下将书中的课后题一一给做了一遍,在此给出书中课后题的答案(非标准答案,是LZ的答案,猿友们可以贡献出自己更快 ...
- SOCKET网络编程细节问题1
SOCKET网络编程快速上手(二)——细节问题(1) 三.细节问题一个也不能少 Socket编程说简单也简单,程序很容易就能跑起来,说麻烦还真是麻烦,程序动不动就出问题.记得刚开始写网络代码的时候,那 ...