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 ...
随机推荐
- VisualSVNServer启动失败错误处理
VisualSVNServerServer service failed to start: 服务已返回特定的服务器错误代码:(0x8007042a) Please check Vis ...
- JVM总结
1. 内存分布: 1). 程序计数器(Program Counter Register)是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器.线程私有.如果线程正在执行的是一个J ...
- PHP用substr截取字符串出现中文乱码问题用mb_substr
PHP用substr截取字符串出现中文乱码问题用mb_substr实例:mb_substr('截取中文乱码问题测试',0,5, 'utf-8'); 语法 : string substr (string ...
- shell脚本小技巧
输入参数错误时,退格会出现^H,这个时候只要在脚本顶部加一条语句:stty erase ^h就可以了 #!/bin/sh stty erase ^h
- Linux workqueue疑问【转】
转自:http://blog.csdn.net/angle_birds/article/details/9387365 各位大神,你们好.我在使用workqueue的过程中遇到一个问题. 项目采用uC ...
- Oracle集合运算符 交集 并集 差集
集合运算符:UNION/UNION ALL 并集,INTERSECT 交集,MINUS 差集 一.union求并集,公共部分只有包含一次 例:求emp表ename中含’A‘或含有‘M’ SQL&g ...
- Linux CentOS 6.5 yum安装MongoDB的操作
安装MongoDB的方法有很多种,可以源代码安装,在CentOS也可以用yum源安装的方法.由于MongoDB更新得比较快,我比较喜欢用yum源安装的方法.64位CentOS下的安装步骤如下: 1.准 ...
- WMsg参数常量值
//WMsg参数常量值: //创建一个窗口 const int WM_CREATE = 0x01; //当一个窗口被破坏时发送 const int WM_DESTROY = 0x02; //移动一个窗 ...
- C#:IText构造PDF文件
IText构造PDF文件 1.1 生成Document Document是我们要生成的PDF文件所有元素的容器,因此要生成一个PDF文档,必须首先定义一个Document对象. Document有三种 ...
- Greenplum failed segment的恢复方法
[前记] Segment检测及故障切换机制GP Master首先会检测Primary状态,如果Primary不可连通,那么将会检测Mirror状态,Primary/Mirror状态总共有4种:1. P ...