C#窗体->>随机四则运算(计算表达式)
用户需求:
程序能接收用户输入的整数答案,并判断对错
程序结束时,统计出答对、答错的题目数量。
补充说明:0——10的整数是随机生成的
用户可以选择四则运算中的一种
用户可以结束程序的运行,并显示统计结果。
在此基础上,做增量开发。
增量内容: 1)处理用户的错误输入,比如输入字母或符号等,处理除法运算中分母为0的情况,处理结果为负数的情况,保证是小学水平不出现负数,比如不能出现5-8=-3这种情况;
2)用户可以设定倒计时;
3)用户可以设定随机整数的范围和题目数量;
4)用户可以选择哪种计算类型,比如加减乘除,或可选择软件随机生成四则运算中的一种;
5)用户可以选择随机生成的题目中是否带有小括号,比如(2+3)*5,如果是gui程序,添加这个功能可以用复选框实现。
6)保证生成过的题目不再重复出现。
设计思路:
因为是做增量啊,所以呢,我在看了5和6这两个增量之后,第一感觉是有点难度。这次和之前的运算不同的地方是:
对于5):加了小括号,这就要考虑优先级了,并且不能再用两个文本框来生成两个数字进行运算了。所以我考虑,把两个文本框合成一个文本框,这样的话就让它来存生成的一个式子,最后只对这个式子进行运算就OK了,这不但可以生成两个数的运算表达式,还可以生成三个数的运算表达式,就看你怎么定义出题方法了。当然了,想的是很简单,毕竟生成的是一个式子而并非两个数进行计算那么简单了。所以我继续分析,就对后面的这个式子进行研究啊。首先它是一个字符串表达式,而进行计算的话肯定不能用string类型的来进行计算。所以用队列把表达式里的每一个数取出来,并定义一个栈,让取出的元素放到栈里,这样的话只对栈里元素用逆波兰式进行计算就可以了。
1.对于实现 出题为一个字符串表达式,我用了如下这种方法:
n1 = ran.Next(int.Parse(textBox4.Text), int.Parse(textBox5.Text)); n2 = ran.Next(int.Parse(textBox4.Text), int.Parse(textBox5.Text)); , int.Parse(textBox5.Text)); textBox1.Text += "("; ) textBox1.Text += "(" + n1 + ")"; else textBox1.Text += n1; , ) == ) textBox1.Text += "+"; else textBox1.Text += "-"; ) textBox1.Text += "(" + n2 + ")"; else textBox1.Text += n2 + ")"; , ) == ) textBox1.Text += "*"+n3; else textBox1.Text += "/" + n3; break;
2.对于让它连续出一种运算的表达式,根据最小取值范围的字符长度,也就是截取第一个运算数后面的运算符来进行判断。如下:
) == "+") { RandomNumjia(); }
3.在准备工作做好之后就是进行计算了:
代码实现:
Form1.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace _Random { public partial class Form1 : Form { public Form1() { InitializeComponent(); } ; ; ; ; private void button1_Click(object sender, EventArgs e) { label2.Text = t.ToString(); timer1.Enabled = true; timer1.Interval = ; timer1.Start(); } private void RDN() { Random ran=new Random(); int n1,n2; if (textBox4.Text==""&&textBox5.Text=="") { MessageBox.Show("请输入取值范围!"); return; } if (checkBox1.Checked == true) ; ; i < int.Parse(textBox6.Text); i++) { textBox1.Clear(); switch (select) { : { n1 = ran.Next(int.Parse(textBox4.Text), int.Parse(textBox5.Text)); n2 = ran.Next(int.Parse(textBox4.Text), int.Parse(textBox5.Text)); , int.Parse(textBox5.Text)); textBox1.Text += "("; ) textBox1.Text += "(" + n1 + ")"; else textBox1.Text += n1; , ) == ) textBox1.Text += "+"; else textBox1.Text += "-"; ) textBox1.Text += "(" + n2 + ")"; else textBox1.Text += n2 + ")"; , ) == ) textBox1.Text += "*"+n3; else textBox1.Text += "/" + n3; break; } } textBox3.Text = ""; } } private void RandomNumjia() { textBox1.Clear(); textBox3.Clear(); if (textBox4.Text == "" && textBox5.Text == "") { MessageBox.Show("请输入取值范围!"); return; } Random ran = new Random(); int n1 = ran.Next(int.Parse(textBox4.Text), int.Parse(textBox5.Text)); int n2 = ran.Next(int.Parse(textBox4.Text), int.Parse(textBox5.Text)); ) textBox1.Text += "(" + n1 + ")"; else textBox1.Text += n1; textBox1.Text += "+"; ) textBox1.Text += "(" + n2 + ")"; else textBox1.Text += n2; } private void RandomNumjian() { textBox1.Clear(); textBox3.Clear(); if (textBox4.Text == "" && textBox5.Text == "") { MessageBox.Show("请输入取值范围!"); return; } Random ran = new Random(); int n1 = ran.Next(int.Parse(textBox4.Text), int.Parse(textBox5.Text)); int n2 = ran.Next(int.Parse(textBox4.Text), int.Parse(textBox5.Text)); ) textBox1.Text += "(" + n1 + ")"; else textBox1.Text += n1; textBox1.Text += "-"; ) textBox1.Text += "(" + n2 + ")"; else textBox1.Text += n2; } private void RandomNumcheng() { textBox1.Clear(); textBox3.Clear(); if (textBox4.Text == "" && textBox5.Text == "") { MessageBox.Show("请输入取值范围!"); return; } Random ran = new Random(); int n1 = ran.Next(int.Parse(textBox4.Text), int.Parse(textBox5.Text)); int n2 = ran.Next(int.Parse(textBox4.Text), int.Parse(textBox5.Text)); ) textBox1.Text += "(" + n1 + ")"; else textBox1.Text += n1; textBox1.Text += "*"; ) textBox1.Text += "(" + n2 + ")"; else textBox1.Text += n2; } private void RandomNumchu() { textBox1.Clear(); textBox3.Clear(); if (textBox4.Text == "" && textBox5.Text == "") { MessageBox.Show("请输入取值范围!"); return; } Random ran = new Random(); int n1 = ran.Next(int.Parse(textBox4.Text), int.Parse(textBox5.Text)); int n2 = ran.Next(int.Parse(textBox4.Text), int.Parse(textBox5.Text)); ) textBox1.Text += "(" + n1 + ")"; else textBox1.Text += n1; textBox1.Text += "/"; ) textBox1.Text += "(" + n2 + ")"; else textBox1.Text += n2; } private void timer1_Tick(object sender, EventArgs e) { ) { timer1.Enabled = false; textBox3.Enabled = false; MessageBox.Show("时间到!"); textBox3.Enabled = false; Form2 frm2 = new Form2(); frm2.ShowDialog(); } t = t - ; label2.Text = t.ToString(); } private void button2_Click(object sender, EventArgs e) { timer1.Stop(); Form2 frm2 = new Form2(); frm2.ShowDialog(); } private void button3_Click(object sender, EventArgs e) { RandomNumjia(); } private void button4_Click(object sender, EventArgs e) { RandomNumjian(); } private void button5_Click(object sender, EventArgs e) { RandomNumcheng(); } private void button6_Click(object sender, EventArgs e) { RandomNumchu(); } private void button7_Click(object sender, EventArgs e) { if (textBox4.Text == "" && textBox5.Text == "") { MessageBox.Show("请输入取值范围!"); return; } else { ; i < int.Parse(textBox6.Text);i++) { RDN(); } } } private void textBox3_KeyDown(object sender, KeyEventArgs e) { string result = textBox1.Text; if (Count == int.Parse(textBox6.Text)) { Form2 frm2 = new Form2(); frm2.ShowDialog(); } if (e.KeyCode == Keys.Enter) { if (textBox3.Text == Calucate(result).ToString()) //直接调用Calucate这个方法计算result的值并与输入的值进行比较 { right++; Count++; MessageBox.Show("回答正确!"); } else { MessageBox.Show("答题错误!"); Count++; string s = textBox1.Text; ) == "+") { RandomNumjia(); } ) == "-") { RandomNumjian(); } ) == "*") { RandomNumcheng(); } ) == "/") { RandomNumchu(); } ) { RDN(); } } string m = textBox1.Text; ) == "+") { RandomNumjia(); } , ) == "-") { RandomNumjian(); } , ) == "*") { RandomNumcheng(); } , ) == "/") { RandomNumchu(); } ) { RDN(); } } } const string operators = "+-*/"; //运算符 static Dictionary<char, int> priorities = null; //优先级 static void Calculator() //添加了四种运算符以及四种运算符的优先级 { priorities = new Dictionary<char, int>(); priorities.Add(); priorities.Add(); priorities.Add(); priorities.Add(); priorities.Add(); } static int Compute(int leftNum, int rightNum, char op) //这是一种方法,用来计算左右两个数的静态方法! { switch (op) { case '+': return leftNum + rightNum; case '-': return leftNum - rightNum; case '*': return leftNum * rightNum; case '/': return leftNum / rightNum; ; } } static bool IsOperator(char op) //每次判断这个字符是否是运算符? { ; } static bool IsAssoc(char op) //返回一个关联符号 { return op == '+' || op == '-' || op == '*' || op == '/'; } static Queue<object> QueueSort (string expression) // 队列排序 { Queue<object> result = new Queue<object>(); Stack<char> operatorStack = new Stack<char>(); //运算符栈 operatorStack.Push('#'); char top, cur, tempChar; //top栈顶,current最近的; string tempNum; , j; i < expression.Length; ) //取出表达式 { cur = expression[i++]; //取出表达式的每个字符赋给cur top = operatorStack.Peek(); //栈顶元素赋给top此时为"#" if (cur == '(') //将左括号压栈,此时栈顶元素为"(" { operatorStack.Push(cur); } else { if (IsOperator(cur)) //如果是运算符的话 { while (IsOperator(top) && ((IsAssoc(cur) && priorities[cur] <= priorities[top])) || (!IsAssoc(cur) && priorities[cur] < priorities[top])) { result.Enqueue(operatorStack.Pop()); //如果元素为运算符并且优先级小于栈顶元素优先级,出栈 top = operatorStack.Peek(); //继续把栈顶元素赋给top } operatorStack.Push(cur); //把数字压栈 } else if (cur == ')') //将右括号添加到结尾 { && (tempChar = operatorStack.Pop()) != '(') { result.Enqueue(tempChar); } } else { tempNum = "" + cur; j = i; '))) { tempNum += expression[j++]; } i = j; result.Enqueue(tempNum); } } } ) { cur = operatorStack.Pop(); if (cur == '#') continue; ) { top = operatorStack.Peek(); } result.Enqueue(cur); } return result; } static int Calucate(string expression) { try { var rpn = QueueSort(expression); //rpn逆波兰表达式reverse polish notation Stack<int> operandStack = new Stack<int>(); int left, right; object cur; ) { cur = rpn.Dequeue(); //出列 if (cur is char) //如果cur为字符的话 { right = operandStack.Pop(); //右边的数字出栈 left = operandStack.Pop(); //左边的数字出栈 operandStack.Push(Compute(left, right, (char)cur)); //此时调用compute方法 } else { operandStack.Push(int.Parse(cur.ToString())); //是数字就压栈 } } return operandStack.Pop(); } catch { throw new Exception("表达式格式不正确!"); } } } }
代码编写过程:
Form2.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace _Random { public partial class Form2 : Form { public Form2() { InitializeComponent(); } private void Form2_Load(object sender, EventArgs e) { textBox1.Text = Form1.Count.ToString(); textBox2.Text = Form1.right.ToString(); textBox3.Text = (Form1.Count - Form1.right).ToString(); } } }
运行过程:
答题的时候给出取值范围,和预想答题数目,然后点击随机,这时程序就会生成一个式子。
当我在输入答案并回车的时候会对生成的式子进行计算,并与输入的答案进行比较。
当时间用完,或者点击结束运算的时候,会弹出测试结果并提示时间到。
PSP耗时分析:
结对编程总结:
说明:我们一起做了1个增量
C#窗体->>随机四则运算(计算表达式)的更多相关文章
- C#窗体->>随机四则运算
用户需求: 程序能接收用户输入的整数答案,并判断对错程序结束时,统计出答对.答错的题目数量.补充说明:0——10的整数是随机生成的用户可以选择四则运算中的一种用户可以结束程序的运行,并显示统计结果.在 ...
- C#窗体随机四则运算 (第四次作业)
---恢复内容开始--- 增量内容:1)处理用户的错误输入,比如输入字母或符号等,处理除法运算中分母为0的情况,处理结果为负数的情况,保证是小学水平不出现负数,比如不能出现5-8=-3这种情况:2)用 ...
- Justinmind使用教程(2)——计算表达式及条件用法
Justinmind的计算表达式以及条件condition的使用对于刚開始学习的人而言比較麻烦. 结合网上了一个教程本文主要针对计算器演示样例进行计算表达式以及条件的使用. 实现目标:依据单位价格(静 ...
- Java集合框架练习-计算表达式的值
最近在看<算法>这本书,正好看到一个计算表达式的问题,于是就打算写一下,也正好熟悉一下Java集合框架的使用,大致测试了一下,没啥问题. import java.util.*; /* * ...
- 随机四则运算 C语言
设计思想:出三十道一百以内数的随机四则运算题目,先随机两个一百以内的数字,再通过随机数确定四则运算算符,最后通过for循环输出三十道 源代码程序: #include <stdlib.h># ...
- C# 字符串计算表达式
C# 字符串计算表达式 string str="4+4+2.1"; 要的效果: double sum=4+4+2.1: 方案一: 动态计算表达式: 1 public class ...
- setTimeout 方法用于在指定的毫秒数后调用函数或计算表达式
setTimeout 方法用于在指定的毫秒数后调用函数或计算表达式
- Asp.Net异常:"由于代码已经过优化或者本机框架位于调用堆栈之上,无法计算表达式的值"的解决方法
今天项目中碰到一个以前从没有见过的异常信息“由于代码已经过优化或者本机框架位于调用堆栈之上,无法计算表达式的值”,于是查了一下资料,原来此异常是由于我在代码中使用了"Response.End ...
- PHP学习之-1.4 计算表达式
计算表达式 不同于HTML和CSS,在PHP中做计算,比如我们写 echo 12*3 计算结果是36.代码如下 <?php echo 12*3;?> 实例 <!DOCTYPE HTM ...
随机推荐
- 视频处理控件TVideoGrabber如何对屏幕进行录制/压缩
TVideoGrabber可以对屏幕进行录制和压缩,本文来详细的说明在多种情况下TVideoGrabber是如何实现屏幕的录制和压缩. 屏幕录制 当VideoSource = vs_ScreenRec ...
- selenium滚动条
element = self.brower.find_element_by_id('xxx')brower.execute_script('arguments[0].scrollIntoView(); ...
- java总结第二次(剩余内容)//类和对象1
7.成员变量和局部变量 成员变量:在类中定义,用来描述对象将要有什么 局部变量:在类的方法中定义,在方法中保存临时数据 区别:作用域不同 局部变量的作用域仅限于定义它的方法 成员变量的作用域在整个类内 ...
- PHP易混淆函数的区分
常量定义自定义常量 常量名区分大小写系统的魔术常量不区分大小写 __DIR__ __dir__变量定义变量名是区分大小写变量名声明时用$符号开头, 而且要符合变量名的命名规则$i;var_dump($ ...
- 浅谈C#当中的out关键字(转载)+说明
与ref关键字一样,out关键字也是按引用来传递的. 示例演示了out关键字的使用方法,其功能是获取数组中的最大值和最大值的索引 using System; using System.Collecti ...
- set_include_path — 设置 include_path 配置选项为当前脚本设置 include_path 运行时的配置选项。
说明 string set_include_path ( string $new_include_path ) 为当前脚本设置 include_path 运行时的配置选项. 参数 new_includ ...
- Java实现批量修改文件名称
import java.io.File; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; /** ...
- [转]关于 initWithNibName 和 loadNibNamed 的区别和联系-iPhone成长之路
转载地址:http://blog.sina.com.cn/s/blog_7b9d64af01018f2u.html 关于 initWithNibName 和 loadNibNamed 的区别和联系.之 ...
- 【转】Windows下搭建cvs服务器
转载地址:http://hi.baidu.com/iloverobot/item/fad1eb6d66c45e166995e66d 下载cvs server:CVSNT 网址为:http://www. ...
- Android Webview实现文件下载功能
在做美图欣赏Android应用的时候,其中有涉及到Android应用下载的功能,这个应用本身其实也比较简单,就是通过WebView控制调用相应的WEB页面进行展示.刚开始以为和普通的文件下载实 ...