运动会分数统计系统 丽水学院C语言课程设计总结报告
第四章 系统设计难点及其解决方法
4.1 栈的四则运算
为了使得关于小数的四则运算更加方便,因此选用了栈作为基本数据结构来完成计算器功能,即可通过直接输入一串表达式直接求出该运算的结果。我运用了栈来处理小数,首先是构建两个栈,分别为OPTR和OPND用来存储加减乘除以及‘#’、(、)等符号和进行运算的各类数据,然后对输入的字符进行逐个判断分类,若读入的是‘0’~‘9’的数字,将其用数组存储起来,直至下一个读入的不再是数字,就利用atoi()将在数组中以字符形式存储的数字字符转化为整形,然后压入数字栈。在字符栈中首先默认压入一个‘#’,之后每次若入栈的字符为运算符或‘#’,就需要与符号栈中的栈顶元素进行比较,通过优先级关系来判定下一步操作是进行四则运算还是继续对符号位进行入栈(优先关系是人为规定的,通过已知的四则运算法则,将各各字符两两之间的关系通过1,0,-1的形式存储在二维数组之中,便于调用),若是等待入栈的符号位比栈顶符号的优先级高则从数字栈中弹出两个数字进行与待入栈符号有关的四则运算;若是等待入栈的符号位与栈顶符号的优先级相等,则脱括号并进行接收下一字符;若是等待入栈的符号位比栈顶符号的优先级低,则将该待入栈的符号也入栈,成为新的栈顶元素。如此反复直至读入的字符为‘#’,说明已经结束,就可以将数字栈中的最后结果输出即可。
4.2 大数的加减乘除
4.2.1 大数的加法
为了使得算法更加简洁易懂,简化运算步骤,方便运算,之前须先定义一个数组倒置的函数Inversion(),在加法运算中,讲存放两个大数的数组进行逆序存放,然后从第一位开始逐项相加减去‘0’存放在sum数组中,而不一开始就进行进位,把两数相加之和以ASCII码的形式存放起来,直到有一个数组已经全部进行累加,然后将另一个没有进行累加的数组中所有的元素通过strcat()加至sum数组之后,然后调用carry()对sum数组从第一位开始进行逐项进位,若是该位大于‘9’,说明已经将和以ASCII码存放起来,就对该位减‘0’的值与10相处后的值与该位的后一位进行累加,并对该位减‘0’的值对10求模再加上‘0’,以字符形式存储一起来,后面几位以此类推,最后若是最高位有进位,就将其字符化存储起来,并在后一位赋0,若是最高位无进位,对后一位直接赋0即可。最后将sum数组倒置(每次倒置最末位始终会有0作为字符串的标记)输出即可。
4.2.2 大数的减法
调用numcomp()对读入的两个字符串进行对比,若是相等说明作差为0,直接输出0即可,
15
运动会分数统计系统 丽水学院C语言课程设计总结报告
若是前者大,从两个字符串的末尾往前逐项作差再加上‘0’,与大数加法相同,将值以ASCII码的形式存储在sub数组中,然后以此类推,直至短的字符串比较完毕,然后将长的字符串中未比较的部分直接赋给sub数组,完成与大数相加类似的操作。与大数相反的,大数相减在最后需要进行的是退位操作,调用abdicate()函数从末尾开始逐一判断,若是小于‘0’,对该位进行加10运算,然后对前一位减一,依次类推。最后调用numclear()进行清零即可(在相减过程中可能会使得最高位甚至前面n位均为0,所以需要清零,找到从第几个位置开始不为0,将后面的数字逐一向前推进,实现该效果)。
4.2.3 大数的乘法
大数乘法利用乘法法则,将短的字符串作为参考系,调用numsm()与长的字符串中的各个字符进行逐项相乘,这里同样以ASCII码进行存储,但是对于9的乘法需要注意的是可能会超出ASCII的数值上线,于是对9进行特殊处理,若读入的数是9,则降低为8并标记为1,在进行逐项相乘,最后再做一次加法即可,然后像大数加法一样进行进位。由于按照乘法法则每位乘法后都会向前进位,因此为了运算方便,每多做一次乘法可以在该字符串的后面多补一个0(在调用numsm()时对引用的短字符串进行长度计算,通过长度来判断要在最后补几个0),最后进行累加即可,依次类推直至该短字符串全部进行乘法运算即可,最后对结果进行进位输出即可。
4.2.3 大数的除法
与大数乘法相同,大数除法是通过减法进行模拟,先比较两个数组的长度,长度之差即是需要进行比较的的次数,而每次比较时作差的次数即是商的某一位的位数,每次从最高位进行比较,一一对字符进行作差,直至短的数组均被减完为止,最后调用退位函数进行退位即可(此时需要注意的是被除数在作差的过程中可能会出现最高位,在下一次进行比较时要被除数的第一位要以第一非零元素算起,保证每次比较都能从两个数字的非零元素开始作差),每次比较对除数数组的每一位进行后移移位,第一位补0,使得其与被除数的非零第一位元素对齐,因此每次比较都会使得除数的长度加1,最后结束循环的条件即是两个数组的长度相等,并且被除数要小于除数。最后就是对商的输出了,只须找到记录商的数组中第一个非0元素,对后面的所有值进行输出即可。
16
运动会分数统计系统 丽水学院C语言课程设计总结报告
第五章 不足之处
该计算器程序基本上实现了简单的计算机功能,在溢出判别,输入错误提示等方面有很好的完善,应用简单的算法实现了大数的加减乘除,用栈实现了小数的四则运算,以及简单的N次方运算,阶乘和累加。
但是在栈的错误输入方面有很大的缺陷,由于栈的组成原理,很难做到在每一次入栈时都能准确进行判别是否出错,一旦出错,栈内还有元素,栈外元素又无法压入,容易造成程序卡壳,无法进行继续操作,或者造成死循环无法结束。
另外在阶乘的算法设计多有不当,阶乘的算法过于简单,由于没有设计大数的阶乘算法,最高的运算次数只有12次,无法实现较大位的阶乘运算。
在结构布置上,菜单的规划不太合理,由于算法不同,分为小数算法和大数算法,因此功能也不是很齐全,无法对所有的运算函数进行循环调用,在模拟菜单的来返,即循环操作的时候使用的函数嵌套使得最后的退出过程过于繁琐,若是在判定是否继续的时候返回主菜单,则无需担心,若是在大数菜单或小数菜单想直接返回主菜单则会使得多次调用主菜单,这就意味着若是想退出主菜单,需要多次输入主菜单的选项6才行,为了尽量弥补这一缺陷,在出现多次嵌套时,会提示继续输入选项6,防止用户觉得程序出错。
界面的设置也不是很美观,只是用了简单的列表式布局。
在算法上虽然已经对代码进行了尽可能的精简,但也并不是最优化的,因此还有待提高。
17
运动会分数统计系统 丽水学院C语言课程设计总结报告
丽水学院工学院C语言课程设计评分表
班级:计16
学号16103330127(24)
姓名:徐明志 机器编号: 5
评价项目 1 完成系统的设计,系统能够正确运行。 25 序评定标准 号 比例 得分 评分实际作品答2 输入测试数据,能够得到正确的结果,并且能够能对输入内容进行数据合法性检测并进行相应的异常处理。 25 3 程序结构合理,有充足的(30%以上)注释。 12 辩成绩 4 在正确的基础上提高效率或者增加创新的一些功能。 13 5 对问题的理解及对源程序的理解。 25 合 计
18