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 ...
随机推荐
- android 项目学习随笔十三(ListView实现ITEM点击事件,将已读状态持久化到本地)
1.因为给LISTVIEW增加了两个头布局,所以在点击事件ITEM索引会增加2,比如原来第一条数据的索引应该为0,增加两个头布局后,它的索引变为 2,为了使LISTVIEW的ITEM在点 ...
- ubuntu安装遇到的问题
检查磁盘发现严重错误 解决办法 进入ubuntu启动菜单,选中*ubuntu后按e进入启动项编辑模式,找到ro rootflags=sync把ro改成rw,再按F10启动 启动后打开终端termina ...
- HttpWebRequest:百度定位当前位置解析
HttpWebRequest request = (System.Net.HttpWebRequest)WebRequest.Create("http://api.map.baidu.com ...
- mysql转换引擎的方法
有很多方法可以将表的存储引擎转换成另外一种引擎,每种方法都各有优缺点: A:alter table 将表从一个引擎直接改为另外一个引擎最简单的办法 alter table tb_name engine ...
- 浮点数转换为人名币读法字符串(JAVA)
/*<java疯狂讲义>浮点数转换为人名币读法字符串这个用例,感觉没有考虑零的情况*/ import java.util.Arrays; public class Num2Rmb { pr ...
- 关于iframe嵌套、动态获取iframe内的url、父页面重定向
1 $(function () { 2 //选择器是选择了easyui中的点击链接,出现新的iframe 3 $("a[target='mainFrame']").click(fu ...
- SIM卡应用-OPN,PLMN,SPN
SIM卡应用 移动运营商已经将SIM卡用於很多不同的应用,下面列出了其中最主要的应 用∶ ·漫游应用∶确保手机可以在漫游之後选择缺省的运营商网络.一个SIM应用是可以在手机漫游到某个合作夥伴运营商网络 ...
- 算法大全(c,c++)
http://www.2cto.com/kf/201109/105758.html 算法大全(C,C++)一. 数论算法 1.求两数的最大公约数function gcd(a,b:integer):in ...
- 如何实现百度外卖APP个人中心头像"浪"起来的动画效果
作为一个中午下班不肯离开工作岗位且勤奋工作的骚年来说,叫外卖就成了不可或缺的习惯.某日瞬间发现百度外卖的APP波浪效果很是吸引人.相比较其他的外卖APP,颜值略高些.(淘宝也有波浪的效果),遂就思考如 ...
- 精通D3.js学习笔记(1)基础的函数
买了本吕大师的d3可视化.最近来学习一下,做个笔记. 1.选择元素 select(第一元素) 和selectAll(全部的元素) 类似css的选择器.也可以是dom选中的. var i ...