一、代码地址
本次作业我们选择的是四则运算,GitHub代码地址如下:
https://github.com/Rafael-Gu/Coop02.git
二、任务分工
驾驶员:顾苡铭(负责代码的编写)
领航员:郑竣太(负责代码的测试)
三、项目成果图:
本模块给出了本题的最终项目效果图:
这就是本题的最终项目成品图。
其中的模块设计中包括了:加减乘除法运算的选择、是否含有符合运算、是否含有小数、是否含有负数等几个模块来设计,以及最终的输出,最终的输出效果图如下:
四、设计过程
本次作业我们选择了C#来进行,因为涉及到了界面的设计以及题目的显示(主要是因为我这个菜鸡想学新花样),于是我们对题目中的加减乘除法、复合运算、是否含有小数、是否含有负数等一些选项设计了一些勾选框,以及针对各类运算设计了多个跳数器,并将最终的结果显示通过显示界面lBoxQuizDisp
来显示出来,最终由使用者来控制文件的保存与输出。生成的文件为txt
的形式。
五、代码部分
因为本次作业采用了C#来进行界面的设计,所以此次的代码分为两个部分:界面设计代码、内部设计代码
关于界面的部分,我们想到了一些问题,我们在选择题目的类型,题目的数量的时候我们想通过选择框的勾选来对题目进行定制,其中加减乘除、复合运算的勾选代码如下:
private void cBoxQTypeAdd_CheckedChanged(object sender, EventArgs e)
{
stpQAdd.Enabled = cBoxQTypeAdd.Checked && cBoxQTypeAdd.Enabled;
if ((sender as CheckBox).Checked)
{
qConfig.eBuilder.Allow(ExprOprt.ADD);
}
else
{
qConfig.eBuilder.Disallow(ExprOprt.ADD);
}
stpQAdd_ValueChanged(stpQAdd, new EventArgs());
}
private void cBoxQTypeSub_CheckedChanged(object sender, EventArgs e)
{
stpQSub.Enabled = cBoxQTypeSub.Checked && cBoxQTypeSub.Enabled;
if ((sender as CheckBox).Checked)
{
qConfig.eBuilder.Allow(ExprOprt.SUB);
}
else
{
qConfig.eBuilder.Disallow(ExprOprt.SUB);
}
stpQSub_ValueChanged(stpQSub, new EventArgs());
}
private void cBoxQTypeMul_CheckedChanged(object sender, EventArgs e)
{
stpQMul.Enabled = cBoxQTypeMul.Checked && cBoxQTypeMul.Enabled;
if ((sender as CheckBox).Checked)
{
qConfig.eBuilder.Allow(ExprOprt.MUL);
}
else
{
qConfig.eBuilder.Disallow(ExprOprt.MUL);
}
stpQMul_ValueChanged(stpQMul, new EventArgs());
}
private void cBoxQTypeDiv_CheckedChanged(object sender, EventArgs e)
{
stpQDiv.Enabled = cBoxQTypeDiv.Checked && cBoxQTypeDiv.Enabled;
if ((sender as CheckBox).Checked)
{
qConfig.eBuilder.Allow(ExprOprt.DIV);
}
else
{
qConfig.eBuilder.Disallow(ExprOprt.DIV);
}
stpQDiv_ValueChanged(stpQDiv, new EventArgs());
}
最后,界面设计代码如下:
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;
using MyExpression;
using System.IO;
namespace 四则运算_生成
{
public partial class FrmQuizGen : Form
{
//private ExprBuilder eBuilder;
private List<Expr> questions = new List<Expr>();//存储生成题目列表
private class QuizConfig
{
public ExprBuilder eBuilder;
public int qcount;
//public bool CplxFlag;
public int addcount, subcount, mulcount, divcount;
public int Count
{
get
{
if (eBuilder.allowCplxExpr)
return qcount;
else
return addcount + subcount + mulcount + divcount;
}
}
public QuizConfig(int addcount, int subcount, int mulcount, int divcount)
{
eBuilder = new ExprBuilder();
this.addcount = addcount;
this.subcount = subcount;
this.mulcount = mulcount;
this.divcount = divcount;
}
}
QuizConfig qConfig;
public FrmQuizGen()
{
qConfig = new QuizConfig(0, 0, 0, 0);
InitializeComponent();
}
private void stpQSub_ValueChanged(object sender, EventArgs e)
{
qConfig.subcount = decimal.ToInt32((sender as NumericUpDown).Value);
}
private void btnClear_Click(object sender, EventArgs e)
{
questions.Clear();
BindingSource bs = new BindingSource();
bs.DataSource = questions;
lBoxQuizDisp.DataSource = bs;
lBoxQuizDisp.DisplayMember = "";
}
private void FrmQuizGen_Activated(object sender, EventArgs e)
{
UpdateCplxSettings();
UpdateStepper();
stpMaxPrecision.Enabled = cBoxAllowFrac.Checked;
BindingSource bs = new BindingSource();
bs.DataSource = questions;
lBoxQuizDisp.DataSource = bs;
lBoxQuizDisp.DisplayMember = "";
}
private void cBoxQTypeAdd_CheckedChanged(object sender, EventArgs e)
{
stpQAdd.Enabled = cBoxQTypeAdd.Checked && cBoxQTypeAdd.Enabled;
if ((sender as CheckBox).Checked)
{
qConfig.eBuilder.Allow(ExprOprt.ADD);
}
else
{
qConfig.eBuilder.Disallow(ExprOprt.ADD);
}
stpQAdd_ValueChanged(stpQAdd, new EventArgs());
}
private void cBoxQTypeSub_CheckedChanged(object sender, EventArgs e)
{
stpQSub.Enabled = cBoxQTypeSub.Checked && cBoxQTypeSub.Enabled;
if ((sender as CheckBox).Checked)
{
qConfig.eBuilder.Allow(ExprOprt.SUB);
}
else
{
qConfig.eBuilder.Disallow(ExprOprt.SUB);
}
stpQSub_ValueChanged(stpQSub, new EventArgs());
}
private void cBoxQTypeMul_CheckedChanged(object sender, EventArgs e)
{
stpQMul.Enabled = cBoxQTypeMul.Checked && cBoxQTypeMul.Enabled;
if ((sender as CheckBox).Checked)
{
qConfig.eBuilder.Allow(ExprOprt.MUL);
}
else
{
qConfig.eBuilder.Disallow(ExprOprt.MUL);
}
stpQMul_ValueChanged(stpQMul, new EventArgs());
}
private void cBoxQTypeDiv_CheckedChanged(object sender, EventArgs e)
{
stpQDiv.Enabled = cBoxQTypeDiv.Checked && cBoxQTypeDiv.Enabled;
if ((sender as CheckBox).Checked)
{
qConfig.eBuilder.Allow(ExprOprt.DIV);
}
else
{
qConfig.eBuilder.Disallow(ExprOprt.DIV);
}
stpQDiv_ValueChanged(stpQDiv, new EventArgs());
}
private void stpMaxOptr_ValueChanged(object sender, EventArgs e)
{
qConfig.eBuilder.maxOpnd = decimal.ToInt32(stpMaxOptr.Value);
}
private void cBoxAllowCplx_CheckedChanged(object sender, EventArgs e)
{
UpdateCplxSettings();
UpdateStepper();
qConfig.eBuilder.allowCplxExpr = (sender as CheckBox).Checked;
if(qConfig.eBuilder.allowCplxExpr)
{
cBoxCQuizAdd_CheckedChanged(cBoxCQuizAdd, new EventArgs());
cBoxCQuizSub_CheckedChanged(cBoxCQuizSub, new EventArgs());
cBoxCQuizMul_CheckedChanged(cBoxCQuizMul, new EventArgs());
cBoxCQuizDiv_CheckedChanged(cBoxCQuizDiv, new EventArgs());
}
else
{
cBoxQTypeAdd_CheckedChanged(cBoxQTypeAdd, new EventArgs());
cBoxQTypeSub_CheckedChanged(cBoxQTypeSub, new EventArgs());
cBoxQTypeMul_CheckedChanged(cBoxQTypeMul, new EventArgs());
cBoxQTypeDiv_CheckedChanged(cBoxQTypeDiv, new EventArgs());
qConfig.addcount = decimal.ToInt32(stpQAdd.Value);
qConfig.subcount = decimal.ToInt32(stpQSub.Value);
qConfig.mulcount = decimal.ToInt32(stpQMul.Value);
qConfig.divcount = decimal.ToInt32(stpQDiv.Value);
}
}
private void UpdateCplxSettings()
{
cBoxQTypeAdd.Enabled = !cBoxAllowCplx.Checked;
cBoxQTypeSub.Enabled = !cBoxAllowCplx.Checked;
cBoxQTypeMul.Enabled = !cBoxAllowCplx.Checked;
cBoxQTypeDiv.Enabled = !cBoxAllowCplx.Checked;
labPromptCQuizNum.Enabled = cBoxAllowCplx.Checked;
labPromptMaxOptr.Enabled = cBoxAllowCplx.Checked;
labPromptAllowType.Enabled = cBoxAllowCplx.Checked;
cBoxCQuizAdd.Enabled = cBoxAllowCplx.Checked;
cBoxCQuizSub.Enabled = cBoxAllowCplx.Checked;
cBoxCQuizMul.Enabled = cBoxAllowCplx.Checked;
cBoxCQuizDiv.Enabled = cBoxAllowCplx.Checked;
cBoxCQuizAllowBrack.Enabled = cBoxAllowCplx.Checked;
stpCQuizNum.Enabled = cBoxAllowCplx.Checked;
stpMaxOptr.Enabled = cBoxAllowCplx.Checked;
}
private void UpdateStepper()
{
stpQAdd.Enabled = cBoxQTypeAdd.Checked && cBoxQTypeAdd.Enabled;
stpQSub.Enabled = cBoxQTypeSub.Checked && cBoxQTypeSub.Enabled;
stpQMul.Enabled = cBoxQTypeMul.Checked && cBoxQTypeMul.Enabled;
stpQDiv.Enabled = cBoxQTypeDiv.Checked && cBoxQTypeDiv.Enabled;
}
private void cBoxAllowFrac_CheckedChanged(object sender, EventArgs e)
{
stpMaxPrecision.Enabled = cBoxAllowFrac.Checked;
qConfig.eBuilder.allowDec = (sender as CheckBox).Checked;
}
private void stpCQuizNum_ValueChanged(object sender, EventArgs e)
{
qConfig.qcount = decimal.ToInt32((sender as NumericUpDown).Value);
}
private void cBoxCQuizAdd_CheckedChanged(object sender, EventArgs e)
{
if ((sender as CheckBox).Checked)
{
qConfig.eBuilder.Allow(ExprOprt.ADD);
}
else
{
qConfig.eBuilder.Disallow(ExprOprt.ADD);
}
}
private void cBoxCQuizSub_CheckedChanged(object sender, EventArgs e)
{
if ((sender as CheckBox).Checked)
{
qConfig.eBuilder.Allow(ExprOprt.SUB);
}
else
{
qConfig.eBuilder.Disallow(ExprOprt.SUB);
}
}
private void cBoxCQuizMul_CheckedChanged(object sender, EventArgs e)
{
if ((sender as CheckBox).Checked)
{
qConfig.eBuilder.Allow(ExprOprt.MUL);
}
else
{
qConfig.eBuilder.Disallow(ExprOprt.MUL);
}
}
private void cBoxCQuizDiv_CheckedChanged(object sender, EventArgs e)
{
if ((sender as CheckBox).Checked)
{
qConfig.eBuilder.Allow(ExprOprt.DIV);
}
else
{
qConfig.eBuilder.Disallow(ExprOprt.DIV);
}
}
private void cBoxCQuizAllowBrack_CheckedChanged(object sender, EventArgs e)
{
qConfig.eBuilder.allowBrack = (sender as CheckBox).Checked;
}
private void stpMaxPrecision_ValueChanged(object sender, EventArgs e)
{
qConfig.eBuilder.maxPrecision = decimal.ToInt32((sender as NumericUpDown).Value);
}
private void stpQAdd_ValueChanged(object sender, EventArgs e)
{
qConfig.addcount = decimal.ToInt32((sender as NumericUpDown).Value);
}
private void stpQMul_ValueChanged(object sender, EventArgs e)
{
qConfig.mulcount = decimal.ToInt32((sender as NumericUpDown).Value);
}
private void stpQDiv_ValueChanged(object sender, EventArgs e)
{
qConfig.divcount = decimal.ToInt32((sender as NumericUpDown).Value);
}
private void lBoxQuizDisp_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void btnGenerate_Click(object sender, EventArgs e)
{
Random r = new Random();
try
{
GenerateQuestions(r);
}
catch (Exception)
{
MessageBox.Show("未选定合适的运算符!");
}
BindingSource bs = new BindingSource();
bs.DataSource = questions;
lBoxQuizDisp.DataSource = bs;
lBoxQuizDisp.DisplayMember = "";
return;
}
private void GenerateQuestions(Random r)
{
if(qConfig.eBuilder.allowOprt == (byte)ExprOprt.NIL)
{
throw new NoOprtFoundException();
}
if(qConfig.eBuilder.allowCplxExpr)
{
for (var i = 0; i < qConfig.Count; i++)
{
try
{
Expr egen = qConfig.eBuilder.Generate(r);
if (egen == null)
{
i--;
continue;
}
questions.Add(egen);
}
catch (Exception)
{
i--;
continue;
}
//questions.Add(egen);
}
}
else
{
int i;
for (i = 0; i < qConfig.addcount;i++)
{
try
{
Expr egen = qConfig.eBuilder.BinaryGenerate(ExprOprt.ADD,r);
if(egen == null)
{
i--;
continue;
}
questions.Add(egen);
}
catch(Exception e)
{
i--;
continue;
}
}
for (i = 0; i < qConfig.subcount; i++)
{
try
{
Expr egen = qConfig.eBuilder.BinaryGenerate(ExprOprt.SUB,r);
if (egen == null)
{
i--;
continue;
}
questions.Add(egen);
}
catch (Exception e)
{
i--;
continue;
}
}
for (i = 0; i < qConfig.mulcount; i++)
{
try
{
Expr egen = qConfig.eBuilder.BinaryGenerate(ExprOprt.MUL,r);
if (egen == null)
{
i--;
continue;
}
questions.Add(egen);
}
catch (Exception e)
{
i--;
continue;
}
}
for (i = 0; i < qConfig.divcount; i++)
{
try
{
Expr egen = qConfig.eBuilder.BinaryGenerate(ExprOprt.DIV,r);
if (egen == null)
{
i--;
continue;
}
questions.Add(egen);
}
catch (Exception e)
{
i--;
continue;
}
}
}
}
private void btnSave_Click(object sender, EventArgs e)
{
StreamWriter wstream;
sfdQuestionstxt.Filter = "文本文件 (*.txt)|*.txt";
sfdQuestionstxt.RestoreDirectory = true;
if(questions.Count > 0)
{
if (sfdQuestionstxt.ShowDialog() == DialogResult.OK)
{
wstream = new StreamWriter(sfdQuestionstxt.FileName);
foreach (var i in questions)
{
wstream.WriteLine(string.Format("{0}=",i));
}
wstream.Flush();
wstream.Close();
MessageBox.Show("保存成功");
}
else
{
MessageBox.Show("保存取消");
}
}
else
{
MessageBox.Show("没有题目");
}
}
private void sfdQuestionstxt_FileOk(object sender, CancelEventArgs e)
{
}
}
}
内部设计程序如下:
using System;
using System.Collections.Generic;
using System.Collections;
using System.Diagnostics;
namespace MyExpression
{
/// <summary>
/// This class builds a complete formula with variety of operations under the spercific constraint
/// </summary>
public class ExprBuilder
{
private List<ExprBase> subExprList;
public bool allowDec;
public bool allowNeg;
public double maxValue;
public int maxPrecision;
public bool allowBrack;
public bool allowCplxExpr;
public int maxOpnd;
public byte allowOprt;
public ExprBuilder()
{
subExprList = new List<ExprBase>();
allowOprt = 0x00;
allowDec = false;
allowNeg = false;
maxValue = 100.0;
maxPrecision = 2;
maxOpnd = 3;
allowBrack = false;
allowCplxExpr = false;
}
public bool IsAllowed(ExprOprt oprt)
{
return (allowOprt & (byte)oprt) != 0;
}
public void Allow(ExprOprt oprt)
{
allowOprt |= (byte)oprt;
}
public void Disallow(ExprOprt oprt)
{
allowOprt = (byte)(allowOprt & ~(int)oprt);
}
/// <summary>
/// Fisher-Yates Shuffle:Shuffle the list of subexpressions to combine.
/// </summary>
private void Shuffle()
{
Random rng = new Random();
int n = subExprList.Count;
while (n > 1)
{
n--;
int k = rng.Next(n + 1);
ExprBase value = subExprList[k];
subExprList[k] = subExprList[n];
subExprList[n] = value;
}
}
private ExprOprt ChooseOprt(Random r = null,params ExprOprt[] oprts)
{
var tick = DateTime.Now.Ticks;
if (r == null)
{
r = new Random();
}
return oprts[r.Next(oprts.Length)];
}
private ExprOprt ChooseOprt(HashSet<ExprOprt> oprtSet,Random r)
{
var oprts = new List<ExprOprt>(oprtSet);
if (r == null)
{
r = new Random();
}
return oprts[r.Next(oprts.Count)];
}
private bool AssociativityEnabled(HashSet<ExprOprt> oprtSet)
{
return oprtSet.Contains(ExprOprt.ADD) || oprtSet.Contains(ExprOprt.MUL);
}
/// <summary>
/// Generate a expression tree based on the constraints.
/// </summary>
public Expr Generate(Random r = null)
{
HashSet<ExprOprt> hsetOprt = new HashSet<ExprOprt>(Enum.GetValues(typeof(ExprOprt)) as IEnumerable<ExprOprt>);
hsetOprt.Remove(ExprOprt.NIL);
if (r == null)
{
var tick = DateTime.Now.Ticks;
r = new Random((int)(tick & 0xffffffffL) | (int)(tick >> 32));
}
if (allowCplxExpr)
{
subExprList.Clear();
#region Random out atomic operands.
for (var i = 0; i < maxOpnd; i++)
{
double dRand = r.NextDouble();
if (allowNeg)
{
dRand -= 0.5;
dRand *= 2;
}
dRand *= maxValue;
if (!allowDec)
{
dRand = Math.Truncate(dRand);
}
else
{
dRand = Math.Round(dRand, maxPrecision);
}
if (allowOprt == (byte)ExprOprt.DIV && Math.Abs(dRand) < double.Epsilon)
{
i--;
continue;
}
AtomExpr aexp = new AtomExpr(dRand);
subExprList.Add(aexp);
}
if (subExprList == null || subExprList.Count <= 0)
{
throw new NoExprFoundException();
}
#endregion
Shuffle();
#region Operator set is culled by allowOprt.
if (!IsAllowed(ExprOprt.ADD))
{
hsetOprt.Remove(ExprOprt.ADD);
}
if (!IsAllowed(ExprOprt.SUB))
{
hsetOprt.Remove(ExprOprt.SUB);
}
if (!IsAllowed(ExprOprt.MUL))
{
hsetOprt.Remove(ExprOprt.MUL);
}
if (!IsAllowed(ExprOprt.DIV))
{
hsetOprt.Remove(ExprOprt.DIV);
}
#endregion
if (hsetOprt.Count == 0)
{
throw new NoOprtFoundException();
}
var origOprtSet = new HashSet<ExprOprt>(hsetOprt);
#region Generating Expression
while (subExprList.Count > 1)
{
Expr ecombine = new Expr();
ExprBase expr0 = subExprList[0];
ExprBase expr1 = subExprList[1];
hsetOprt = new HashSet<ExprOprt>(origOprtSet);
if (Math.Abs(expr1.ParseValue()) < double.Epsilon)
{
hsetOprt.Remove(ExprOprt.DIV);
}
if (!allowBrack)
{
if (!allowNeg && (expr0.ParseValue() < expr1.ParseValue()))
{
//不允许负数出现,若左<右则不允许减法为合并运算
hsetOprt.Remove(ExprOprt.SUB);
}
if (AssociativityEnabled(hsetOprt))
{
if (expr1 is Expr)
{
if (expr1.Priority == 1 || (expr1 as Expr).oprt == ExprOprt.SUB)
{
hsetOprt.Remove(ExprOprt.SUB);
}
if (!expr1.Associative)
{
//(expr1 as Expr).InvertOprt();
hsetOprt.Remove(ExprOprt.DIV);
}
if (expr0.Priority == 0 || expr1.Priority == 0)
{
hsetOprt.Remove(ExprOprt.MUL);
hsetOprt.Remove(ExprOprt.DIV);
}
}
else
{
if (expr0.Priority == 0)
{
hsetOprt.Remove(ExprOprt.MUL);
hsetOprt.Remove(ExprOprt.DIV);
}
}
}
else
{
if (expr0 is Expr)
{
if (expr0.Priority == 0)
{
hsetOprt.Remove(ExprOprt.DIV);
}
}
}
}
if (hsetOprt.Count == 0)
{
throw new NoOprtFoundException();
}
ecombine.expr0 = expr0;
ecombine.expr1 = expr1;
ecombine.oprt = ChooseOprt(hsetOprt,r);
if (!allowBrack && !ecombine.IsNaturalOrder)
{
return null;
}
if (AssociativityEnabled(hsetOprt))
{
subExprList.Remove(expr0);
subExprList.Remove(expr1);
subExprList.Add(ecombine);
Shuffle();
}
else
{
subExprList[0] = ecombine;
subExprList.Remove(expr1);
}
}
return subExprList[0] as Expr;
#endregion
}
else
{
double dRand = r.NextDouble();
if (allowNeg)
{
dRand -= 0.5;
dRand *= 2;
}
dRand *= maxValue;
if (!allowDec)
{
dRand = Math.Truncate(dRand);
}
else
{
dRand = Math.Round(dRand, maxPrecision);
}
AtomExpr aexp0 = new AtomExpr(dRand);
dRand = r.NextDouble();
if (allowNeg)
{
dRand -= 0.5;
dRand *= 2;
}
dRand *= maxValue;
if (!allowDec)
{
dRand = Math.Truncate(dRand);
}
else
{
dRand = Math.Round(dRand, maxPrecision);
}
AtomExpr aexp1 = new AtomExpr(dRand);
Expr ecombine = new Expr();
if(!allowNeg)
{
if (aexp0.ParseValue()<aexp1.ParseValue())
{
hsetOprt.Remove(ExprOprt.SUB);
}
}
if(aexp1.ParseValue()==0)
{
hsetOprt.Remove(ExprOprt.DIV);
}
ecombine.oprt = ChooseOprt(hsetOprt,r);
ecombine.expr0 = aexp0;
ecombine.expr1 = aexp1;
return ecombine;
}
}
public Expr BinaryGenerate(ExprOprt oprt, Random r = null)
{
Expr ecombine = new Expr();
if (r == null)
{
r = new Random();
}
if (oprt == ExprOprt.NIL)
{
return null;
}
else
{
ecombine.oprt = oprt;
}
double dRand0 = r.NextDouble();
double dRand1 = r.NextDouble();
if (allowNeg)
{
dRand0 -= 0.5;
dRand0 *= 2;
dRand1 -= 0.5;
dRand1 *= 2;
}
else
{
if (dRand0 < dRand1)
{
var t = dRand0;
dRand0 = dRand1;
dRand1 = t;
}
}
while (oprt == ExprOprt.DIV && Math.Truncate(Math.Abs(dRand1) * maxValue) < double.Epsilon)
{
dRand1 = r.NextDouble();
if (allowNeg)
dRand1 = (dRand1 - 0.5) * 2;
}
dRand0 *= maxValue;
dRand1 *= maxValue;
if (!allowDec)
{
dRand0 = Math.Truncate(dRand0);
dRand1 = Math.Truncate(dRand1);
}
else
{
dRand0 = Math.Round(dRand0, maxPrecision);
dRand1 = Math.Round(dRand0, maxPrecision);
}
AtomExpr aexp0 = new AtomExpr(dRand0);
AtomExpr aexp1 = new AtomExpr(dRand1);
ecombine.expr0 = aexp0;
ecombine.expr1 = aexp1;
return ecombine;
}
}
public class NoExprFoundException : Exception
{
public NoExprFoundException() : base("
No available expressions!
(Possibly maxOpnd is 0)
")
{
}
}
public class NoOprtFoundException : Exception
{
public NoOprtFoundException():base("
No available operators!
(Possibly hsetOprt is empty)
")
{
}
}
}
五、作业总结
本次作业感谢搭档对我的极大的帮助,让我这个小白可以接触到C#这门语言,并将其运用到本次作业当中。对于本次作业我想说,这次作业确实量很大,占用了不少的假期时间,让我的北京之旅非常难忘,让我第一次体验到了旅游的同时,还得熬夜做作业的赶脚。不过这次作业真正让我感受到的是C#真的很厉害,真的很方便!它让我从根本上了解到了程序设计中的界面设计以及按键设计的过程。其中在代码的设计过程中,我们遇到了很多问题,例如:式子的生成以及如何表现出来的问题。对于这个问题我们花了近2天的时间来进行设计,从最初的随机生成,到最后的由字符串生成,并最终由二叉树表现出来,这一模块的设计耗费了最大的时间与精力。
其中我要感谢领航员郑竣太的帮助,他在C#语言的教学上起到了很大的作用,他在教我的时候花费了不少的精力,但是他还是很耐心地叫我使用C#语言,非常感谢。