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 ...
随机推荐
- Visual Studio 2015 & C#6.0 试用报告,持续更新。
昨天早上看到了.net开源的消息,我是非常兴奋的,毕竟局限于Windows的.NET经常被人唾弃.VB暂且不提,C#常年被人指责跨平台性不佳,我也是无能为力.即使有Mono等第三方跨平台工程,.NET ...
- 成C++应用程序世界------异常处理
一. 概述 C++自身有着很强的纠错能力,发展到现在,已经建立了比較完好的异常处理机制.C++的异常情况无非两种,一种是语法错误,即程序中出现了错误的语句,函数,结构和类,致使编译程序无法进行.还有一 ...
- js实现文字横向滚动
页面布局 <div id="scroll_div" class="fl"> <div id="scroll ...
- having在Oracle和mysql小点不同
在Oracle中,having一定要结合group by使用,但在mysql中,情况就不一样了.能够单独使用. C:\Documents and Settings\guogang>sqlplus ...
- 什么是Solr搜索
什么是Solr搜索 一.Solr综述 什么是Solr搜索 我们经常会用到搜索功能,所以也比较熟悉,这里就简单的介绍一下搜索的原理. 当然只是介绍solr的原理,并不是搜索引擎的原理,那会更复杂. ...
- Build MySQL 5.7.4 in RedHat
Install Cmake 1. download cmake source code at http://www.cmake.org/files/v3.1/cmake-3.1.0.tar.gz 2 ...
- C#排序算法
随笔- 41 文章- 0 评论- 25 C#排序算法小结 前言 算法这个东西其实在开发中很少用到,特别是web开发中,但是算法也很重要,因为任何的程序,任何的软件,都是由很多的算法和数据结构 ...
- 测试驱动 ASP.NET MVC Type Aliase
Type Aliase 去掉Scala的糖衣(4) -- Type Aliase 我的新博客地址:http://cuipengfei.me/blog/2013/12/23/desugar-scala- ...
- UTF8国际通用为什么还要用GBK?
前序: 一直对编码很痴迷,让数据一目了然不好吗?为什么要去编码,这不是闲的没事,浪费生产力吗? 随着学习的深入,愈加觉得自己无知,世界语言千万种,在互联网的世界里如何表示他们?碰到汉字ASCii就显得 ...
- java使用maven创建springmvc web项目
创建maven项目,使用maven-archetype-webapp 创建完成后首先是在pom.xml里增加maven的依赖 <dependencies> <dependency&g ...