https://git.coding.net/Aojim_Lee/lianxi.git
一.需求分析:
可控制题目数量的四则运算出题软件,
要求单个题目中至少出现两种运算符,
运算符个数控制在3~5个之间,
要求运算数值大小在0~100之间
运算过程中不得出现小数、负数
二.功能设计
满足题设基本功能,实现100以内自然数的四则运算
三.设计实现
Main:主类,负责控制题目个数,调用Build类创建文件,输出算式
Generate:函数构造类,负责出题,并测试运算过程是否符合需求,调用运算类将生成的式子完整化
Calculator:运算类,负责运算出函数构造类生成的式子
Build:文件创建类,负责创建文件,调用Generate类,将产生的式子以循环的方式打印到创建的文件当中
四.算法详解
鉴于在中序表达式中,计算机无法处理运算符的先后顺序问题,故将生成的运算式子利用栈分别存放数字和运算符,再转换成为计算机可处理的后序表达式
五.测试运行
六.代码
class Generate{
public static String generateQ(){
String[] operator = {"+","-","*","÷"};
Random random = new Random();
int qLen = random.nextInt(3) + 3;
int[] num = new int[qLen+1]; //运算数个数
for(int n=0;n<qLen;n++){
num[n] = random.nextInt(100)+1;
}
int[] op = new int[qLen+1];
for(int i=0;i<qLen;i++){
op[i] =random.nextInt(4);
int judge=0;
if(i>0){
if(op[i]==op[i-1]){
judge++;
}
}
if(i==qLen-1){
//System.out.println("---");
if(judge==i){
i--;
}
}
}
num[qLen] = random.nextInt(100)+1;
for(int j=0;j<qLen;j++){
if(op[j]==1){ //算式中出现减号时对于数据的控制
if(op[j+1]==2){ //对于减号后紧跟乘号所产生的减数放大问题的处理
if(num[j]-(num[j+1]*num[j+2])<0){
num[j+1]=random.nextInt(100)+1;
num[j+2]=random.nextInt(100)+1;
}
}
else{
if(num[j]<num[j+1]){
num[j+1] = random.nextInt(100)+1;
}
}
}
if(op[j]==3){ //对于算式中除号的处理
num[j+1]=random.nextInt(10)+1;
num[j]=(random.nextInt(9)+2)*num[j+1];
if(op[j+1]==3){
op[j+1] = random.nextInt(3); //禁止连除
}
}
if(j>0){ //当减号前出现除号导致被减数便小问题的处理
if(op[j]==1 && op[j-1]==3){
while(num[j-1]/num[j]-num[j+1]<0){
num[j+1]=random.nextInt(100)+1;
}
}
}
}
String text = new String();//生成算式
if(qLen == 3){
text = num[0]+operator[op[0]]+num[1]+operator[op[1]]+num[2]+operator[op[2]]+num[3];
}
if(qLen == 4){
text = num[0]+operator[op[0]]+num[1]+operator[op[1]]+num[2]+operator[op[2]]+num[3]+operator[op[3]]+num[4];
}
if(qLen == 5){
text = num[0]+operator[op[0]]+num[1]+operator[op[1]]+num[2]+operator[op[2]]+num[3]+operator[op[3]]+num[4]+operator[op[4]]+num[5];
}
System.out.println("^^^" + text);
int answer = Calculator.calQ(text);
text = text + "=" + answer;
return text;
}
}
class Calculator{
static private int getw(char c){
if(c=='*' || c=='÷') return 2;
else if(c=='+' || c=='-') return 1;
else return -1;
}
static private int calc(int a, int b, char c) {
//System.out.println("**" + a + " " + c + " " + b);
if(c == '+') return a + b;
else if(c == '-') return a - b;
else if(c == '*') return a * b;
else if(c == '÷') return a / b;
else return -1;
}
static public int calQ(String text){
char[] te = new char[100];
te = text.toCharArray();
int[] numList = new int[20];//数组存放数字
char[] opList = new char[20];//数组存放操作符
int temp = 0, pn = -1, pc = -1;//中间变量与栈顶元素
for(int i=0;i<te.length;i++){
if(Character.isDigit(te[i])){
temp = temp*10 + te[i]-'0';//字符转换
if(i == te.length-1){
numList[++pn] = temp;
}
}
else{
//System.out.println("++++" + te[i]);
numList[++pn] = temp;
temp = 0;
while(pc!=-1 && getw(opList[pc])>=getw(te[i])){
int num1 = numList[pn--];
int num2 = numList[pn--];
char te1 = opList[pc--];
numList[++pn] = calc(num2,num1,te1);
}
opList[++pc] = te[i];
}
}
return numList[0];
}
}
七.总结
一开始在看到这个题目的时候,内心是真的在颤抖,因为的确是知道自己有几斤几两,也开始尝试着再去把原本没有学好的,忘得差不多的java从头捡起来,每天也都是花了不少的时间去刷慕课,到了周四才发现,这种学习方法实在是一种错误,因为短时间内根本无法从头再来,于是自己也开始静下心来,在网上搜索相关的博客,找到对应的知识点进行攻克,其中也看了不少积极的同学的代码,也询问了相关同学在算法上面的一些理解,然后才发现有针对性的去学习的时候效率才是最高的,虽然时间还是不够,但是越到快接近期限时间的时候,就逼自己逼迫的越紧凑,等到真正敲完,才发现,真心是学到了不少的东西