标签:
>>>>>直接上代码,问题出在随机分数的生成上,确实出现了一些非常鱼唇的错误,不过已经提交了就没办法了,在这里发出来仅供参考吧:
修改前:
1 public static Fraction nextFrac(int width, Random seed)
2 {
3 Random rd = seed;
4 int down1 = (int)(rd.NextDouble() * (width - 1) + 1);//随机生成低于width的分母
5 int quo1 = (int)(rd.NextDouble() * (width - 2) + 1);//随机生成低于width-1的带分数整数部分
6 long up1 = (long)(rd.NextDouble() * (width - 1) + 1);//随机生成低于width的分子 8 up1 += quo1*down1;
9 return new Fraction(up1, down1);
10 }
修改后:
1 public static Fraction nextFrac(int width, Random seed)
2 {
3 Random rd = seed;
4 int down1 = (int)(rd.NextDouble() * (width - 1) + 1);//随机生成低于width的分母
5 long up1 = (long)(rd.NextDouble() * (width *down1-1) + 1);//随机生成低于分母*width的分子7 return new Fraction(up1, down1);
8 }
对于随机数元素的生成范围,第一次要求作业中有如下规定:
使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围,例如
Myapp.exe -r 10
将生成10以内(不包括10)的四则运算题目
对于我之前的处理方法,即 分数 = 整数[1,width-1)+ 分子[1,width)/分母[1,width)
其值域实际上为[1,2*width-2),而且导致生成的分数至少大于1,实际上少了很多种情况...............................................
特别的,当width取2时,由于width-2=0,随机数失去意义,这样取值范围就固定变成了[1,2],这就与老师在课程要求上的说明冲突了;
同理可得:
1 int down1 = (int)(rd.NextDouble() * (width - 1) + 1);
2 long up1 = (long)(rd.NextDouble() * (width *width-1) + 1);
这样的处理方式也是存在问题的,值域实际上变成了[1,width^2)
值得说明的一点是,仍然保留了random*(width-1)+1这一设定,以规避分母或分子为0的情况,主要是为了减少无意义操作数(0)的出现频率和规避一些不合法情况
程序设计过程中出现的其他Bug汇总:
1.当范围较大,运行批改程序读取表达式计算结果时,容易出现分子超int范围的情况,笔者在之前的博客中已经提到过,为了支持足够的范围,需要采用Long整型存储分子分母,因为计算过程中可能出现超int范围的分子分母结果,因此相应的,读取答案的时候,我们也要采用Int64.Parse来录入结果,并用相应的Long型变量存储,而非Int32.Parse
2.求最大公约数,也即约分的方法一定要考虑传入参数含0的情况,以及,需要考虑,对于公约数为0的情况,约分时应当怎样处理,是否需要报异常等
3.对于计算模块,自栈顶向下逐步运算时,一定要考虑前一个操作符是否为“-”号,对于没有添加括号的情况,盲目按序运算会导致错误 如 (3-2-1),当计算完一个括号内的值后,需要取前一个运算符判断是否为×或÷,因为在这两个符号后面跟括号的情况下,其运算会被延后,一旦其后所跟的括号内式子得出结果,该运算应当被首先考虑。
例如:(6×5+8÷(3-2))
操作过程为:
自左向右,先算6×5,因÷号后有左括号,除法运算被延迟,操作数8和运算“÷”,“(”被压入栈,加减法均压入栈不动,一直读到第一个”)“自右往左运算,得到(3-2)结果为1,然后立即计算8÷1,再加上6×5即可
4.在用Directionary<String,List<String>>这一数据结构时发现索键求值的过程存在很多数据错误,因此自己写了一个小的CaseList类将List封装了起来,经测试就不存在数据混乱问题了,原因不明,代码如下:
1 class CaseList
2 {
3 private List<String> usedCase = new List<String>();
4 public int getCount()
5 {
6 return this.usedCase.Count;
7 }
8
9 public void AddRange(List<String> list)
10 {
11 foreach (String s in list)
12 {
13 usedCase.Add(s);
14 }
15 }
16
17 public String getValue(int index)
18 {
19 return usedCase.ElementAt(index);
20 }
21
22 public bool ContainsValue(String Answer)
23 {
24 foreach (String s in usedCase)
25 {
26 if (Answer.Equals(s)) return true;
27 }
28 return false;
29 }
30
31 public static implicit operator CaseList(List<String> s)
32 {
33 CaseList c = new CaseList();
34 c.AddRange(s);
35 return c;
36 }
37
38 }
标签:
原文地址:http://www.cnblogs.com/kibbon/p/4832024.html