计算类的封装
jisuan.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace ZY四则运算
7 {
8 public class jisuan
9 {
10 public Dictionary<char, int> priorities = null; //优先级
11
12 public void Calculator() //添加了四种运算符以及四种运算符的优先级
13 {
14 priorities = new Dictionary<char, int>();
15 priorities.Add('#', -1);
16 priorities.Add('+', 0);
17 priorities.Add('-', 0);
18 priorities.Add('*', 1);
19 priorities.Add('/', 1);
20 }
21
22 const string operators = "+-*/"; //运算符
23
24 public double Compute(double leftNum, double rightNum, char op) //这是一种方法,用来计算左右两个数的静态方法!
25 {
26 switch (op)
27 {
28 case '+': return leftNum + rightNum;
29 case '-': return leftNum - rightNum;
30 case '*': return leftNum * rightNum;
31 case '/': return leftNum / rightNum;
32 default: return 0;
33 }
34 }
35
36 public bool IsOperator(char op) //每次判断这个字符是否是运算符?
37 {
38 return operators.IndexOf(op) >= 0;
39 }
40
41 public bool IsAssoc(char op) //返回一个关联符号
42 {
43 return op == '+' || op == '-' || op == '*' || op == '/';
44 }
45
46 public Queue<object> QueueSort(string expression) // 队列排序
47 {
48 Queue<object> result = new Queue<object>();
49 Stack<char> operatorStack = new Stack<char>(); //运算符栈
50 operatorStack.Push('#');
51 char top, cur, tempChar; //top栈顶,current最近的;
52 string tempNum;
53 for (int i = 0, j; i < expression.Length; ) //取出表达式
54 {
55 cur = expression[i++]; //取出表达式的每个字符赋给cur
56 top = operatorStack.Peek(); //栈顶元素赋给top此时为"#"
57
58 if (cur == '(') //将左括号压栈,此时栈顶元素为"("
59 {
60 operatorStack.Push(cur);
61 }
62 else
63 {
64 if (IsOperator(cur)) //如果是运算符的话
65 {
66 while (IsOperator(top) && ((IsAssoc(cur) && priorities[cur] <= priorities[top])) || (!IsAssoc(cur) && priorities[cur] < priorities[top]))
67 {
68 result.Enqueue(operatorStack.Pop()); //如果元素为运算符并且优先级小于栈顶元素优先级,出栈
69 top = operatorStack.Peek(); //继续把栈顶元素赋给top
70 }
71 operatorStack.Push(cur); //把数字压栈
72 }
73 else if (cur == ')') //将右括号添加到结尾
74 {
75 while (operatorStack.Count > 0 && (tempChar = operatorStack.Pop()) != '(')
76 {
77 result.Enqueue(tempChar);
78 }
79 }
80 else
81 {
82 tempNum = "" + cur;
83 j = i;
84 while (j < expression.Length && (expression[j] == '.' || (expression[j] >= '0' && expression[j] <= '9')))
85 {
86 tempNum += expression[j++];
87 }
88 i = j;
89 result.Enqueue(tempNum);
90 }
91 }
92 }
93 while (operatorStack.Count > 0)
94 {
95 cur = operatorStack.Pop();
96 if (cur == '#') continue;
97 if (operatorStack.Count > 0)
98 {
99 top = operatorStack.Peek();
100 }
101
102 result.Enqueue(cur);
103 }
104
105 return result;
106 }
107
108 public double Calucate(string expression)
109 {
110 try
111 {
112 var rpn = QueueSort(expression);
113 Stack<double> operandStack = new Stack<double>();
114 double left, right;
115 object cur;
116 while (rpn.Count > 0)
117 {
118 cur = rpn.Dequeue(); //出列
119 if (cur is char) //如果cur为字符的话
120 {
121 right = operandStack.Pop(); //右边的数字出栈
122 left = operandStack.Pop(); //左边的数字出栈
123 operandStack.Push(Compute(left, right, (char)cur)); //此时调用compute方法
124 }
125 else
126 {
127 operandStack.Push(double.Parse(cur.ToString())); //是数字就压栈
128 }
129 }
130 return operandStack.Pop();
131 }
132 catch
133 {
134 throw new Exception("表达式不正确!");
135 }
136 }
137 }
138 }
Form1.cs
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Linq;
7 using System.Text;
8 using System.Windows.Forms;
9 using System.IO;
10
11 namespace ZY四则运算
12 {
13 public partial class Form1 : Form
14 {
15 Form2 frm2 = new Form2();
16 public Form1()
17 {
18 InitializeComponent();
19 }
20 private void button1_Click_1(object sender, EventArgs e)
21 {
22 string Express = textBox1.Text;
23 frm2.listBox1.Items.Add(Express);
24 listBox1.Items.Add(" " + Express + "=");
25 textBox1.Clear();
26 }
27 private void button2_Click(object sender, EventArgs e)
28 {
29 frm2.ShowDialog();
30 }
31 }
32 }
Form2.cs
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Linq;
7 using System.Text;
8 using System.Windows.Forms;
9 using System.IO;
10
11 namespace ZY四则运算
12 {
13 public partial class Form2 : Form
14 {
15 public Form2()
16 {
17 InitializeComponent();
18 }
19 int time = 40; //倒计时
20 int Count = 0;
21 int right = 0;
22 private void Form2_Load(object sender, EventArgs e)
23 {
24 lblTime.Text = "剩余时间:";
25 timer1.Enabled = false;
26 timer1.Interval = 1000;
27 }
28 private void timer1_Tick(object sender, EventArgs e)
29 {
30 int tm = time--;
31 lblTime.Text = "剩余时间:" + tm.ToString() + "秒";
32 if (tm == 0)
33 {
34 timer1.Enabled = false;
35 MessageBox.Show("时间已到", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
36 }
37 }
38 private void button1_Click_1(object sender, EventArgs e)
39 {
40 timer1.Stop();
41 MessageBox.Show(label1.Text);
42 }
43 private void button2_Click_1(object sender, EventArgs e)
44 {
45 timer1.Start();
46 }
47 private void button3_Click_1(object sender, EventArgs e)
48 {
49 sfd.Filter = "(*.txt)|*.txt";
50 if (sfd.ShowDialog() == DialogResult.OK)
51 {
52 string sPath = sfd.FileName;
53 FileStream fs = new FileStream(sPath, FileMode.Create);
54 StreamWriter sw = new StreamWriter(fs, Encoding.UTF8);
55 int iCount = listBox2.Items.Count - 1;
56 for (int i = 0; i <= iCount; i++)
57 {
58 sw.WriteLine(listBox2.Items[i].ToString());
59 }
60 sw.Flush();
61 sw.Close();
62 fs.Close();
63 }
64 }
65 private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
66 {
67 if (listBox1.Items.Count > 0)
68 {
69 textBox1.Text = listBox1.Items[0].ToString();
70 }
71 else
72 {
73 MessageBox.Show("答题结束");
74 }
75 }
76 private void textBox2_KeyDown(object sender, KeyEventArgs e)
77 {
78 jisuan js = new jisuan();
79 if (e.KeyCode == Keys.Enter)
80 {
81 string result = textBox1.Text;
82 if (textBox2.Text.Trim() == string.Empty) //去除空格之后,如果没答题给出提示。
83 {
84 MessageBox.Show("您尚未答题", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
85 return;
86 }
87 Count++;
88 if (textBox2.Text ==js.Calucate(result).ToString()) //直接调用Calucate这个方法计算result的值并与输入的值进行比较
89 {
90 MessageBox.Show("回答正确!");
91 listBox2.Items.Add(result + "=" + textBox2.Text + " " + "√");//若答对直接后面打个对勾。
92 listBox1.Items.Remove(listBox1.SelectedItem);
93 right++;
94 }
95
96 else
97 {
98 MessageBox.Show("答题错误!");
99 listBox2.Items.Add(result + "=" + textBox2.Text + " " + "×");//若答错就在后面打个错号。
100 listBox1.Items.Remove(listBox1.SelectedItem);
101 }
102 label1.Text = "正确率:" + Convert.ToString(right * 1.0 / Count * 100).PadRight(5, ' ').Substring(0, 5) + "%";
103 textBox1.Clear();
104 textBox2.Clear();
105 }
106 }
107 }
108 }
运行测试:
出题界面:
答题界面:
提示结束:
保存: