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

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

  之前得到一个栈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. 对于发Github的contributions贡献不会增加

    最近发现每天在 Github 做代码提交,可是 contributions 的面板(贡献图)上的绿点(即贡献值)却没有增长了.擦~ 有两个礼拜了. 例如以下图并且.同一时候发现曾经的绿点也是稀稀拉拉的 ...

  2. Qlik Sense Desktop

    2014年新一代的报表利器 Qlik Sense Desktop 初步体验 2014-09-22 12:45 by BIWORK, 974 阅读, 7 评论, 收藏, 编辑 Qlik Sense De ...

  3. !DOCTYPE html文档类型声明简写 HTML5 DOCTYPE缩写

    html5之!DOCTYPE html文档类型声明简写,在HTML5中DOCTYPE简写非常重要. 一.概述   -   TOP 让CSS样式表生效,DOCTYPE声明是必须的,以前TABLE布局的网 ...

  4. .net图片快速去底(去除白色背景)

    public System.Drawing.Bitmap KnockOutGzf(String path) { System.Drawing.Image image = System.Drawing. ...

  5. Roslyn 编译平台概述

    在Language Feature Status上面看到,其实更新的并不是特别多,为了不会误导看了C# 6.0 功能预览 (一)的园友,现在把官方的更新列表拿了过来,供大家参考 C# 6.0 功能预览 ...

  6. CString转换为const char*

    CString str=_T("这是我的测试程序.");// 先得到要转换为字符的长度const size_t strsize=(str.GetLength()+1)*2; // ...

  7. Ninject是一款.Net平台下的开源依赖注入框架

    Ninject是一款.Net平台下的开源依赖注入框架.按照官方说法,它快如闪电.超级轻量,且充分利用了.Net的最新语法,使用Lambda表达式代替Xml文件完成类型绑定.Ninject结构精巧,功能 ...

  8. ASP.NET开发的大型网站有哪些架构方式

    谈谈用ASP.NET开发的大型网站有哪些架构方式(成本) 在上篇文章里(http://www.cnblogs.com/ms0017/archive/2011/07/26/2117676.html),列 ...

  9. iOS基础 - NSURLSession

    使用URLSession所有的网络访问都是有缓存的,缓存文件自动保存在tmp文件夹中,URLSession本身实现的时候,就是少量多次的! l 使用defaultSessionConfiguratio ...

  10. 基于python的《Hadoop权威指南》一书中气象数据下载和map reduce化数据处理及其可视化

    文档内容: 1:下载<hadoop权威指南>中的气象数据 2:对下载的气象数据归档整理并读取数据 3:对气象数据进行map reduce进行处理 关键词:<Hadoop权威指南> ...