需求分析
首先明确项目需要,一个可以定做小学四则运算的程序。所以需要我们能够随机生成不同的四则运算,范围应在100以内,包含“+,-,*,÷”四种操作。要求:不存在小数,题目尽量不重复。
功能设计
基本功能应当包括,读入用户想要定制的算式数,以及对应的运算符数量,然后生成对应数目和难度的四则运算式子。并由程序自己计算,给出相应的答案。
扩展功能可以用:在算式中包含括号,计算存在真分数的式子。
设计实现
由计算机生成随机的第一个数字、运算符、后续数字、完成计算、显示结果等等。
在生成后续数字时,可以限定生成条件以保证运算结果不会出现分数和负数的情况。
代码详解
Lib类中
1 static String createFormula() 2 { 3 int digital, sign = 0; 4 char symbol = 0; 5 String formula = ""; 6 7 digital = (int)(Math.random()*20); 8 formula = formula + digital; 9 10 for(int i=0; i<5; i++) 11 { 12 if(sign >= 2) 13 sign = (int)(Math.random()*2); 14 else sign = (int)(Math.random()*4); 15 16 if(sign == 0) { 17 symbol = ‘+‘; 18 digital = (int)(Math.random()*20+1); 19 } 20 else if(sign == 1) { 21 symbol = ‘-‘; 22 digital = (int)(Math.random()*digital+1); //??è¥é?ò???digital 23 } 24 else if(sign == 2) { 25 symbol = ‘*‘; 26 digital = (int)(Math.random()*(100/(digital+1))+1); 27 28 } 29 else if(sign == 3) { 30 symbol = ‘÷‘; 31 for(int j=2; j<=digital; j++) 32 if(digital%j == 0) { 33 digital = j; 34 break; 35 } 36 } 37 formula = formula + symbol + digital; 38 } 39 return formula; 40 }
使用createFormula()创建算式,:
1、随机生成算式第一个数(20以内)
2、依次确定(生成)五个运算符以及第二个数字
(1)sign用于避免出现连续的“乘”、“除”运算(原理:sign随机确定运算符,sign的上一个值>=2时,后面生成的运算符只有“+”、“-”)
(2)为避免出现负数,当sign为“-”时,后一个数的生成范围为“比上一个数小”
(3)当sign为“×”时,为避免出现大雨100的结果,第二个数的生成范围为[0,100/上一个数]
(4)当sign为“÷”时,为保证不出现分数,第二个数为 [2~第一个数] 这个范围内找“第一个数的因数”生成
3、实现字符串拼接
static int answerFormula(String formula)
{
char[] charArray = formula.toCharArray();
int[] stackForInt = new int[10];
char[] stackForChar = new char[10];
int topOfInt = -1, topOfChar = -1, num = 0;
for(int i=0; i<charArray.length; i++){
//System.out.println(i+" :"+topOfInt+" "+topOfChar);
if(Character.isDigit(charArray[i])) {
num = num*10 + charArray[i]-‘0‘;
if(i == charArray.length - 1)
stackForInt[++topOfInt] = num;
}
else {
stackForInt[++topOfInt] = num;
num = 0;
if(topOfChar == -1) stackForChar[++topOfChar] = charArray[i];
else if(charArray[i]==‘*‘ || charArray[i]==‘÷‘) {
if(stackForChar[topOfChar] == ‘*‘ || stackForChar[topOfChar] == ‘÷‘) {
int num1 = stackForInt[topOfInt--];
int num2 = stackForInt[topOfInt--];
char symbol = stackForChar[topOfChar--];
if(symbol == ‘*‘) stackForInt[++topOfInt] = num1 * num2;
else if(symbol == ‘÷‘) stackForInt[++topOfInt] = num2 / num1;
stackForChar[++topOfChar] = charArray[i];
}
else if(stackForChar[topOfChar] == ‘+‘ || stackForChar[topOfChar] == ‘-‘) {
stackForChar[++topOfChar] = charArray[i];
}
}
else if(charArray[i]==‘+‘ || charArray[i]==‘-‘) {
if(topOfChar == -1) stackForChar[++topOfChar] = charArray[i];
else {
while(topOfChar != -1) {
int num1 = stackForInt[topOfInt--];
int num2 = stackForInt[topOfInt--];
char symbol = stackForChar[topOfChar--];
if(symbol == ‘+‘) stackForInt[++topOfInt] = num1 + num2;
else if(symbol == ‘-‘) stackForInt[++topOfInt] = num2 - num1;
else if(symbol == ‘*‘) stackForInt[++topOfInt] = num1 * num2;
else if(symbol == ‘÷‘) stackForInt[++topOfInt] = num2 / num1;
}
}
stackForChar[++topOfChar] = charArray[i];
}
}
}
while(topOfChar!=-1) {
int num1 = stackForInt[topOfInt--];
int num2 = stackForInt[topOfInt--];
char symbol = stackForChar[topOfChar--];
if(symbol == ‘+‘) stackForInt[++topOfInt] = num1 + num2;
else if(symbol == ‘-‘) stackForInt[++topOfInt] = num2 - num1;
else if(symbol == ‘*‘) stackForInt[++topOfInt] = num1 * num2;
else if(symbol == ‘÷‘) stackForInt[++topOfInt] = num2 / num1;
}
return stackForInt[0];
}
答案部分:使用中序运算式转成后序运算式以计算表达式
1、stackForInt:模拟int栈
2、stackForChar:模拟字符栈
3、topOfChar / topOfInt:模拟栈顶
将string类型的算式转化成数组
用中序运算读取字符数字并计算得出答案
static void printFormula(String[] formulaList, int n)throws IOException
{
FileOutputStream fs = new FileOutputStream(new File("result.txt"));
PrintStream p = new PrintStream(fs);
p.println("2016012036");
for(int i=0; i<n; i++)
p.println(formulaList[i]);
p.close();
}
在result中显示结果(优先显示学号信息)
在Main中
public static void main(String args[])
{
Scanner input = new Scanner(System.in);
int n;
n = input.nextInt();
String[] formulaList = new String[50];
for(int i=0; i<n; i++)
{
formulaList[i] = Lib.createFormula();
//System.out.println(formula);
int answer = Lib.answerFormula(formulaList[i]);
formulaList[i] = formulaList[i] + ‘=‘ + answer;
}
try {
Lib.printFormula(formulaList, n);
}
catch(IOException ioe) {
ioe.printStackTrace();
}
}
主函数循环n次,生成n个式子并完成计算,catch异常。
结果展示

基本实现了基础功能
用“模块化”将代码分块实现,避免了很多不必要的麻烦,整个项目实现起来也更加流畅,思路更加清晰,对效率的提高有很大帮助。
PSP展示
这次作业战线拉得特别长,从分块方式等开始慢慢构思,很多思考过程都是在平时的生活中完成的,而且在实现过程中因为不熟练,每天的进度非常低,所以并没有使用PSP……而且之前也败在没有真正习惯事先定好时间计划,所以实在没办法进行PSP展示。