【个人项目总结】四则运算生成器
项目需求:
像阿超那样,花二十分钟写一个能自动生成小学四则运算题目的命令行 “软件”, 分别满足下面的各种需求。下面这些需求都可以用命令行参数的形式来指定:
a) 除了整数以外,还要支持真分数的四则运算。 (例如: 1/6 + 1/8 = 7/24)
b) 让程序能接受用户输入答案,并判定对错。 最后给出总共 对/错 的数量。
c) 逐步扩展功能和可以支持的表达式类型,最后希望能支持下面类型的题目 (最多 10 个运算符,括号的数量不限制):
25 - 3 * 4 - 2 / 2 + 89 = ?
1/2 + 1/3 - 1/4 = ?
(5 - 4 ) * (3 +28) =?
d) 一次可以批量出 100 道以上的题目,保存在文本文件中, 并且保证题目不能重复,(1+2) 和 (2+1) 是重复的题目。
我的实现:
我了解到我的同学们大多都是用前、中、后缀表达式的互相转换来实现算式计算的,这个算法在上学期的课中编写过了,所以我想用个不一样的方法实现。
我使用了C#的反射,动态生成、编译代码。这样,只要在程序中生成了中缀表达式,将其转换为String型然后插入动态代码中编译,即可直接算出结果。
代码动态创建及编译的核心代码:
1 // 1.CSharpCodePrivoder 2 CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider(); 3 4 // 2.ICodeComplier 5 ICodeCompiler objICodeCompiler = objCSharpCodePrivoder.CreateCompiler(); 6 7 // 3.CompilerParameters 8 CompilerParameters objCompilerParameters = new CompilerParameters(); 9 objCompilerParameters.ReferencedAssemblies.Add("System.dll"); 10 objCompilerParameters.GenerateExecutable = false; 11 objCompilerParameters.GenerateInMemory = true; 12 13 // 4.CompilerResults 14 GenerateLines(); 15 Console.WriteLine("==========No." + (i+1).ToString() + "=========="); 16 Console.WriteLine(lines); 17 18 CompilerResults cr = objICodeCompiler.CompileAssemblyFromSource(objCompilerParameters, GenerateCode()); 19 20 if (cr.Errors.HasErrors) 21 { 22 Console.WriteLine("编译错误:"); 23 foreach (CompilerError err in cr.Errors) 24 { 25 Console.WriteLine(err.ErrorText); 26 } 27 } 28 else 29 { 30 //通过反射,调用HelloWorld的实例 31 Assembly objAssembly = cr.CompiledAssembly; 32 object objHelloWorld = objAssembly.CreateInstance("DynamicCodeGenerate.HelloWorld"); 33 MethodInfo objMI = objHelloWorld.GetType().GetMethod("OutPut"); 34 string re = objMI.Invoke(objHelloWorld, null).ToString(); 35 }
其中,GenerateCode()是我用来生成代码的函数,返回了一个需要被动态编译的代码,其中定义了namespace DynamicCodeGenerate,public class HelloWorld以及其下方法public string OutPut()。
代码生成函数GenerateCode()的主要功能即是生成算式。因为题目要求程序可以计算分数,所以GenerateCode()还需要能进行通分、约分的操作。
GenerateCode()函数的主要流程:生成随机数,产生一个中缀表达式;对表达式全通分(即每一项都乘上所有被除项之积),然后将得数与刚才乘上的数约分,即得到分数形式的答案。
之后接受用户输入,和标准答案比对后输出结果即可。
完整代码:
1 using System; 2 using System.Reflection; 3 using System.Globalization; 4 using Microsoft.CSharp; 5 using System.CodeDom; 6 using System.CodeDom.Compiler; 7 using System.Text; 8 using System.Collections.Generic; 9 using System.IO; 10 11 namespace A_Boring_Project_CSharp 12 { 13 class Program 14 { 15 static int max = 50; 16 static int rows = 10; 17 static List<int> nums; 18 static List<int> add_n_minus; 19 static List<int> div; 20 static List<int> div_nums; 21 static int tf; 22 static int amount; 23 static string lines; 24 static string lines_tf; 25 static string lines_final; 26 static int count; 27 28 static void Main(string[] args) 29 { 30 31 lines = ""; 32 count = 0; 33 34 for (int i = 0; i < rows; i++) 35 { 36 // 1.CSharpCodePrivoder 37 CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider(); 38 39 // 2.ICodeComplier 40 ICodeCompiler objICodeCompiler = objCSharpCodePrivoder.CreateCompiler(); 41 42 // 3.CompilerParameters 43 CompilerParameters objCompilerParameters = new CompilerParameters(); 44 objCompilerParameters.ReferencedAssemblies.Add("System.dll"); 45 objCompilerParameters.GenerateExecutable = false; 46 objCompilerParameters.GenerateInMemory = true; 47 48 // 4.CompilerResults 49 GenerateLines(); 50 Console.WriteLine("==========No." + (i+1).ToString() + "=========="); 51 Console.WriteLine(lines); 52 53 CompilerResults cr = objICodeCompiler.CompileAssemblyFromSource(objCompilerParameters, GenerateCode()); 54 55 if (cr.Errors.HasErrors) 56 { 57 Console.WriteLine("编译错误:"); 58 foreach (CompilerError err in cr.Errors) 59 { 60 Console.WriteLine(err.ErrorText); 61 } 62 } 63 else 64 { 65 //通过反射,调用HelloWorld的实例 66 Assembly objAssembly = cr.CompiledAssembly; 67 object objHelloWorld = objAssembly.CreateInstance("DynamicCodeGenerate.HelloWorld"); 68 MethodInfo objMI = objHelloWorld.GetType().GetMethod("OutPut"); 69 string re = objMI.Invoke(objHelloWorld, null).ToString(); 70 71 string answer = Console.ReadLine(); 72 73 if (re == answer) 74 { 75 count++; 76 Console.WriteLine("Correct"); 77 } 78 else 79 { 80 Console.WriteLine("Wrong, the answer should be " + re.ToString()); 81 } 82 } 83 } 84 Console.WriteLine("Your score is: " + count.ToString() + " out of " + rows.ToString()); 85 Console.ReadLine(); 86 } 87 88 static string GenerateCode() 89 { 90 91 StringBuilder sb = new StringBuilder(); 92 sb.Append("using System;using System.IO;using System.Collections.Generic;using System.Text;"); 93 sb.Append(Environment.NewLine); 94 sb.Append("namespace DynamicCodeGenerate"); 95 sb.Append(Environment.NewLine); 96 sb.Append("{"); 97 sb.Append(Environment.NewLine); 98 sb.Append("\tpublic class HelloWorld"); 99 sb.Append(Environment.NewLine); 100 sb.Append("\t{"); 101 sb.Append(Environment.NewLine); 102 sb.Append("\tpublic string OutPut()"); 103 sb.Append(Environment.NewLine); 104 sb.Append("\t\t{"); 105 sb.Append(Environment.NewLine); 106 sb.Append("long tf = "+ tf + ";"); 107 sb.Append(Environment.NewLine); 108 sb.Append("long re = " + lines_final + ";"); 109 sb.Append(Environment.NewLine); 110 sb.Append("for (int i = 2; i < re || i < tf; i++){while (re % i == 0 && tf % i == 0){re = re / i;tf = tf / i;}}"); 111 sb.Append(Environment.NewLine); 112 sb.Append("Console.Write(\"Result = \");"); 113 sb.Append("\t\tif (tf != 1){return re.ToString() + \"/\" + tf.ToString();} else{return re.ToString();}"); 114 sb.Append(Environment.NewLine); 115 sb.Append(Environment.NewLine); 116 sb.Append("\t\t}"); 117 sb.Append(Environment.NewLine); 118 sb.Append("\t}"); 119 sb.Append(Environment.NewLine); 120 sb.Append("}"); 121 122 string code = sb.ToString(); 123 124 return code; 125 } 126 127 static void GenerateLines() 128 { 129 tf = 1; 130 nums = new List<int>(); 131 add_n_minus = new List<int>(); 132 div = new List<int>(); 133 div_nums = new List<int>(); 134 System.Random rnd = new System.Random(GetRandomSeed()); 135 amount = rnd.Next(1, 11); 136 lines = ""; 137 lines_tf = ""; 138 lines_final = ""; 139 140 int x = 0; 141 int d = 0; 142 List<int> anm; 143 List<int> op; 144 anm = new List<int>(); 145 op = new List<int>(); 146 for (int i = 0; i < amount; i++) 147 { 148 //A new number 149 rnd = new System.Random(GetRandomSeed()); 150 nums.Add(rnd.Next(1, max)); 151 lines += nums[i]; 152 //A new operator 153 System.Random rnd0 = new System.Random(GetRandomSeed()); 154 int key = rnd0.Next(0,4); 155 op.Add(lines.Length + 1); 156 switch (key) 157 { 158 case 0: 159 anm.Add(i); 160 x = 0; 161 lines += "+"; 162 add_n_minus.Add(lines.Length); 163 break; 164 case 1: 165 anm.Add(i); 166 x = 0; 167 lines += "-"; 168 add_n_minus.Add(lines.Length); 169 break; 170 case 2: 171 x++; 172 if (x <= 3) 173 { 174 lines += "*"; 175 break; 176 } 177 else 178 { 179 goto case 1; 180 } 181 case 3: 182 x = 0; 183 d++; 184 if (d <= 3) 185 { 186 lines += "/"; 187 div.Add(i); 188 break; 189 } 190 else 191 { 192 goto case 1; 193 } 194 default: 195 x = 0; 196 break; 197 } 198 } 199 op.Add(lines.Length); 200 201 rnd = new System.Random(GetRandomSeed()); 202 nums.Add(rnd.Next(1, max)); 203 lines += nums[amount]; 204 205 for (int i = 0; i < div.Count; i++) 206 { 207 div_nums.Add(nums[div[i] + 1]); 208 lines_tf += div_nums[i]; 209 lines_tf += "*"; 210 tf *= div_nums[i]; 211 } 212 213 lines_final += lines_tf; 214 lines_final += lines; 215 216 if (div.Count > 0) 217 { 218 for (int i = 1; i <= add_n_minus.Count; i++) 219 { 220 lines_final = lines_final.Insert(i * lines_tf.Length + add_n_minus[i - 1], lines_tf); 221 } 222 } 223 224 } 225 226 static int GetRandomSeed() 227 { 228 byte[] bytes = new byte[4]; 229 System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider(); 230 rng.GetBytes(bytes); 231 return BitConverter.ToInt32(bytes, 0); 232 } 233 234 } 235 }
小结:
在写GenerateCode()函数时,没有预先设计好控制、变量等等的具体实现,所以最终导致代码有点混乱,下次应该多加注意。
转载于:https://www.cnblogs.com/yuki8819/p/5305107.html
【个人项目总结】四则运算生成器相关推荐
- 作业五—个人项目-小学四则运算 “软件”之升级版1
作业五-个人项目-小学四则运算 "软件"之升级版 作业要求来源:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/21 ...
- 小学四则运算生成器(Java实现)
跳转详细介绍的博客:小学四则运算生成器(Java实现) 实现效果图: 开始运行程序 未输入生成题目数量及数值范围 输入数值 随机生成题目 用户输入并提交答案,后台将用户答案与正确答案进行校正,统计正确 ...
- 【软件工程基础】结对项目之四则运算题目生成
[软件工程基础]结对项目之四则运算题目生成 一,项目介绍 项目的github地址:https://github.com/qqqqqianru/sizeyunsuantimushengcheng 二.项 ...
- 2017202110104-高级软件工程第二次作业个人项目之-四则运算生成程序
GitHub项目地址 https://github.com/Cynnn/Arithmatic PSP2.1表格 PSP2.1 Personal Software Process Stages 预估耗时 ...
- 第三次作业:个人项目-小学四则运算 “软件”之初版
本次作业要求来自于:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/2166 我的项目GitHub远程仓库地址:https://gith ...
- 高级软件工程2017第2次作业—— 个人项目:四则运算题目生成程序(基于控制台)...
Deadline:2017-09-27(周三) 21:00pm (注:以下内容参考 福大软工作业 和集大个人作业 ) 0.前言 很多童鞋在本课程的目标和规划中,都表示希望能提高自己的实践能力. Pra ...
- 作业四 | 个人项目-小学四则运算 “软件”之初版
作业要求来自于https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/2186 GitHub远程仓库的地址https://github.com/ ...
- 【结对编程】四则运算生成器
结对项目报告 源码及接口说明地址:https://github.com/hzphzp/ArithmeticCore/tree/master/ArithmeticCore 一.功能实现 按照用户设置的要 ...
- react小项目 - canvas海报生成器
1.背景 之前做过一个营销类移动端h5项目-海报生成器,上传用户本地图片合成海报并支持下载,这次有时间了整理整理. 2.几个重点 上传本地图片并支持预览 处理ios照片翻转 使用canvas对图片 ...
最新文章
- 用 Python 写 3D 游戏,太赞了
- 常用计算机主要硬件设备,个人计算机常用的输出设备41.计算机硬件的组成部分主要包括:...
- 微信小程序——添加按钮格式
- RoFormerV2:自然语言理解的极限探索
- sql server 2012远程链接的方法及步骤
- Node.js中事件的循环
- Linux---信号及其使用简单讲解
- css_selector定位总结
- uBLAS——Boost 线性代数基础程序库
- jquery系列教程8-jquery插件大全
- node 连接mysql 中间件_如何在node.js里连接和使用mysql
- oracle12c集群安装—grid安装
- 硬件第二节 MOS管电路工作原理及详解
- python2 之 DataFrame
- 面试:Android应用的崩溃率
- 计算机电脑用英语单词怎么读,计算器 英语
- 同步时序逻辑电路功能分析之同步五进制加法计数器
- Python生信练习——hg38每条染色体基因,转录本的分布
- ora-29861: 域索引标记为loading/failed/unusable
- 图解Topo拓扑排序
热门文章
- php cms选择,php cms 选择哪个好?
- 无法支持python程序的编辑运行和调试_解决pycharm的Python console不能调试当前程序的问题...
- 初始化 数组 java_如何用Java初始化数组
- objective-c教程_Objective-C Hello世界教程
- 斯威夫特山地车_斯威夫特枚举
- java se面试题_Java SE 8面试问答(第2部分)
- Spring @Service批注
- hadoop和hdfs命令_Hadoop 1.x和2.x HDFS基本开发人员命令,“ hadoop”命令
- Sobel边缘检测算法及OpenCV函数实现
- 解决ubuntu下arduino IDE的Serial Port无法选择问题