GIT地址 | https://github.com/WHYNOTEN |
GIT用户名 | WHYNOTEN |
学号后五位 | 41215 |
博客地址 | https://www.cnblogs.com/SW-P-WY/ |
作业链接 | 作业链接 |
一.环境配置过程
1.VS2017
由于上学期学习C#时已经安装过并配置好了环境,这里就不再赘述
2.Git
(1).Git安装很简单,直接官网下载.exe文件即可,有可能会因为服务器问题出现下载失败的情况,我的解决办法是用手机开热点下载,就不会出现这个问题了。具体原理不清楚,这是上次从github下载一个开源项目得到方法(当时没有Wifi只能手机开热点,结果发现速度很快而且不会中断)。下载好后,在任意位置右击鼠标,即可看到如图,点击Gig Bash Here即可打开Git终端,然后依次输入
git config --global user.name "John Doe"
git config --global user.email进行个人信息配置即可
配置好信息即可关闭窗口。
二.代码设计思路
分析本次题目要求:
1.随机n道生成四则运算式;
2.操作符为2个或3个;
3.题目出现的除法必须为整除,同时不能出现负数;
4.语言要求使用C#;
5.将题目以及答案写入txt文件中
考虑到代码量可能比较大,于是在命名空间下构建一个新的类Class1进行取值,判断,计算;
对于随机取数可以直接使用Random.Next(min,max)实现,该方法接收两个参数最小值min,最大值max,返回值为区间内任意整数,对于操作符数目随机也可采取同样方法。而对于随机操作符,可以采用下标随机,定义常量Const = "+-*/",随机获得0-3的值,利用下标值取出字符串中符号即可。下面为代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
//定义字符串类型保存+-*/ private String Const = "+-*/"; //定义静态随机对象 private static Random rd = new Random(3); //随机赋值函数 public void RandValues() { this.account = rd.Next(3, 5); if (this.account == 3) { this.Assit(5); } else { this.Assit(7); } } //辅助赋值函数 private void Assit(int a) { for (int i = 1; i <= a; i++) { if (i % 2 == 0) { //随机获得操作符 int index = rd.Next(0, 4); this.question.Add(this.Const[index].ToString()); } else { //随机获得操作数 this.question.Add(rd.Next(1, 101).ToString()); } } }
题中要求满足除法为整除且不能出现负数,则利用函数进行判断,由于对绘图软件使用后不熟悉,手绘了判断流程:
判断除法,减法是否符合规则函数
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
//对减法与除法进行判断 private bool Judge(int num1, string str1, int num2) { switch (str1) { case "/": if (num1 % num2 == 0) { return true; } else { return false; } case "-": if (num1 < num2) { return false; } else { return true; } default: return false; } }
利用递归对整个算式的除法,减法进行判断,以及对乘法进行运算
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
//递归函数,判断算式中所有的除法是否为非整除 private bool JudgeDiv(List<string> args) { int index = args.IndexOf("/"); if (index == -1) { return true; } else { int num1 = Convert.ToInt32(args[index - 1]); int num2 = Convert.ToInt32(args[index + 1]); if (this.Judge(num1, "/", num2)) { args.RemoveAt(index - 1); args.RemoveAt(index - 1); args.RemoveAt(index - 1); args.Insert(index - 1, (num1 / num2).ToString()); return JudgeDiv(args); } else { return false; } } } //递归函数,当算式中除法符合规范时,对乘法进行计算 //便于对减法进行判断 private List<string> Multi(List<string> args_2) { int index = args_2.IndexOf("*"); if (index == -1) { return args_2; } else { int num1 = Convert.ToInt32(args_2[index - 1]); int num2 = Convert.ToInt32(args_2[index + 1]); args_2.RemoveAt(index - 1); args_2.RemoveAt(index - 1); args_2.RemoveAt(index - 1); args_2.Insert(index - 1, (num1 / num2).ToString()); return Multi(args_2); } } //对减法进行规则判定 private bool Subtrace(List<string> args_3) { int index = args_3.IndexOf("-"); if (index == -1) { return true; } else { int num1 = Convert.ToInt32(args_3[index - 1]); int num2 = Convert.ToInt32(args_3[index + 1]); if (this.Judge(num1, "-", num2)) { args_3.RemoveAt(index - 1); args_3.RemoveAt(index - 1); args_3.RemoveAt(index - 1); args_3.Insert(index - 1, (num1 - num2).ToString()); return JudgeDiv(args_3); } else { return false; } } }
利用System.IO中的FileInfo进行文件写入
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
////写入文件 private void ToFile(List<string> a) { FileInfo fileInfo = new FileInfo(@"C:\Users\Administrator\Desktop\github\Calculator\WHYNOTEN\Calculator\Calculator\r.txt"); // 通过则将算式保存,返回 StreamWriter sw = fileInfo.AppendText(); foreach(string _ in a) { sw.Write(_); } sw.Close(); }
最后一个综合函数依次调用除法判断函数,乘法运算函数,减法判断函数
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
public void Comprehensive() { this.RandValues(); List<string> temp = new List<string>(); temp = this.CopyList(); //除法判断 if (this.JudgeDiv(temp)) { //除法判定通过,进行乘法运算 this.Multi(temp); //进行减法判定 if (this.Subtrace(temp)) { String question_ = ""; foreach(string _ in this.question) { question_ += _; } int answer = Convert.ToInt32(this.cal.Compute(question_, null)); //检查最终结果是否为负数 if (answer>=0) { this.question.Add("="); this.question.Add(Convert.ToString(answer)); this.question.Add("\n"); this.ToFile(this.question); this.ClearVars(); } else { this.ClearVars(); this.Comprehensive(); } } else { //未通过则清空变量再次生成 this.ClearVars(); this.Comprehensive(); } } else { //未通过则清空变量再次生成 this.ClearVars(); this.Comprehensive(); } }
最后在Program的Main()中进行调用生成
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
Class1 a = new Class1(); int sum = GetAccount(); //循环调用生成函数,进行多道题目生成 for (int i = 0; i < sum; i++) { a.Comprehensive(); } foreach (string _ in Class1.vs) { Console.Write(_); }
下面时程序运行截图
三.从克隆项目以及上传项目
1.克隆项目,利用Git命令git clone url(url为克隆链接地址),获取方式为下图所示,如果要指定克隆的分支,可以利用命令git clone -b 分支名称 url (例如:git clone -b cplusplus url)
2.上传项目,在第一步已经将仓库添加到了自己账号下,此时复制仓库地址url,
右键想要上传的项目,选择Git Bash Here,输入命令git clone url,将仓库复制到本地,此时会多出一个与仓库同名的文件夹(红圈标记),将本地项目所有文件复制到新出现的文件夹中,
然后配置一下账户信息(用户名与eamil同自己的github账号)
接着在Git终端进入新文件夹依次输入命令 git add . (注意,不要漏掉add后面的.,此步是将新文件夹下的文件都添加进来)
git commit -m "提交信息"(提交信息根据自己情况填写) git push -u origin master(打包文件)
git push(将文件上传仓库)
上传成功
四.单元测试,回归测试以及调试
单元测试:
右击解决方案,选择添加新建项目,再选择测试,添加单元测试
解决方案管理栏目会出现单元测试项目,自动生成一个测试文件
随后右击单元测试项目的引用,将测试的代码引用进去,记得在测试文件using 项目名称,不能只在管理资源添加。
最后写入测试代码进行测试(笔者项目有两个类,Class1.cs是进行生成算式和写入文件的类,Program.cs是Main()函数所在类,进行获取题目数目以及调用Class1生成题目)
在Class1.cs中有一个bool变量test,如果Class1.cs进行了成功生成题目,该变量会被赋值为true,这里对这个变量的值进行断言,看是否为true
随后点击上方测试,选择运行所有测试,然后会跳出结果,绿色的勾代表测试通过
注意:单元测试一定要有断言Assert没有断言的测试作用都不大
调试:
由于对于回归测试不太明白,就不再进行这步操作,下面进行调试步骤
断点调试,在VS中,可以在行号旁左击快速为该行打上断点,VS对断点数目没有要求,进行调试时会在第一个断点进行停留,继续调试会进入下一个断点,直至所有断点调试完毕
断点调试快捷键为F5,会将程序运行至断点处,此时可以对变量值进行查看,也可以对堆栈情况,CPU使用进行监视
当然当不清楚具体错误出现的大概位置时,不太好确定断点在何处,VS也提供了逐语句调试以及逐过程调试
性能测试:VS提供了很方便的性能测试工具,右击分析选择性能探查器,选择分析方式,即可快速进行性能分析,这里选择第一个,对象分配跟踪,查看占用字节情况
五.感想
在做的时候感觉自己能说好多的,这突然搞定了,又不知道说啥了。总的来说吧,这次的作业,难度有点大,特别是代码的设计,写了很久重构了三次(主要还是很多数据结构相关知识以及算法相关知识太少了)。遇到的最大的问题就是C# 中的Random()类,生成重复数据,最终在网上找到了很多解决方案,但是看得懂的没几个,都不太明白实现原理,最后看到了一篇CSDN的文章很简单的就解决,就是将Random()定义为静态类型,成为一个静态变量。(附上地址)另外一个问题当然就是关于git的问题了,好在有一个同学总结了他的方法放在群里,得以省去很多查资料的步骤。过程虽然艰难,但是完成的一刻还是很开心的。