四则运算网页版
Posted Mr.缪
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了四则运算网页版相关的知识,希望对你有一定的参考价值。
在第三次实验的基础上,teacher又对此提出了新的要求,实现网页版或安卓的四则运算。
结对开发伙伴:
博客名:斗破2
姓名:王文奇
博客链接:http://www.cnblogs.com/qwer111/
详细网页四则运算要求:
1、生成的题目中计算过程不能产生负数,也就是说算术表达式中如果存在e1-e2的子表达式,那么结果大于等于0;
2、生成的题目中如果存在形式如e1/e2的子表达式,那么其结果应该是真分数。
3、每道题目中出现的运算符个数不超过3个,括号不做详细要求。
问题分析:
在第三次实验的基础上,要求把C++语言转换成java语言,即把cpp文件程序转换为java,jsp文件。但由于C和java在全局变量和栈的应用上有一定的不同,在对栈的使用中由于出栈和读取栈顶元素都为Object对象转换起来比较麻烦,所以我们在原先cpp文件中栈的应用改成了数组来实现压栈入栈。因为是网页版的所以就会使用jsp,html与java文件之间的数据交换,我们通过session,request和调用返回函数等方法来实现数据交互。
所遇困难:
1、在使用java中的栈时,出栈元素难以转换为所要类型。
2、jsp之间传递数组返回nill.
3、jsp与java之间的数据交互。
解决办法:
1、因为是顺序栈,所以直接使用数组来实现栈的所有功能
2、使用session来传递数组
3、在class文件中书写一个返回函数,在new生成对象时自动传递数组
前cpp文件:
1 #include<iostream> 2 #include<string> 3 #include<sstream> 4 #include<time.h> 5 #include<iomanip> 6 #include<fstream> 7 #define MAX 100 8 using namespace std; 9 10 stringstream formula; //当前算式 11 string buffer[MAX]; //缓冲区数组 12 int TopNumber; //上限 13 int BaseNumber; //下限 14 int IsMulDlvExist; //是否有乘除 15 int Amount; //操作数的个数 16 int BracketNum; //括号个数 17 int LBraket[2]; //左括号的位置 18 int RBraket[2]; //右括号的位置 19 int IsNeg; //是否有负数 20 int IsRem; //是否有余数 21 int IsBra; //是否有括号 22 int IsRep; //是否重复 23 float Result[MAX]; //正确结果数组 24 char lastOp; //记录上个运算符是否为除号 25 26 //优先级数组 27 char prior[7][7] = { 28 { \'>\', \'>\', \'<\', \'<\', \'<\', \'>\', \'>\' }, 29 { \'>\', \'>\', \'<\', \'<\', \'<\', \'>\', \'>\' }, 30 { \'>\', \'>\', \'>\', \'>\', \'<\', \'>\', \'>\' }, 31 { \'>\', \'>\', \'>\', \'>\', \'<\', \'>\', \'>\' }, 32 { \'<\', \'<\', \'<\', \'<\', \'<\', \'=\', \' \' }, 33 { \'>\', \'>\', \'>\', \'>\', \' \', \'>\', \'>\' }, 34 { \'<\', \'<\', \'<\', \'<\', \'<\', \' \', \'=\' } 35 }; 36 //操作符栈 37 typedef struct { 38 char *base; 39 char *top; 40 }OperChar; 41 //操作数栈 42 typedef struct{ 43 float *base; 44 float *top; 45 }NumberLink; 46 //初始化栈 47 void InitOperStack(OperChar &S) 48 { 49 S.base = new char[MAX]; 50 if (!S.base) 51 exit(1); 52 S.top = S.base; 53 } 54 void InitNumStack(NumberLink &S) 55 { 56 S.base = new float[MAX]; 57 if (!S.base) 58 exit(1); 59 S.top = S.base; 60 } 61 //进栈 62 void PushOper(OperChar &S,char e){ 63 if (S.top - S.base == MAX) 64 exit(1); 65 *S.top++ = e; 66 67 } 68 void PushNum(NumberLink &S,float e){ 69 if (S.top - S.base == MAX) 70 exit(1); 71 *S.top++ = e; 72 } 73 //出栈 74 void PopOper(OperChar &S, char &e) 75 { 76 if (S.top == S.base) 77 exit(1); 78 e = *--S.top; 79 } 80 void PopNum(NumberLink &S, float &e) 81 { 82 if (S.top == S.base) 83 exit(1); 84 e = *--S.top; 85 } 86 //取栈顶元素 87 char GetTopOper(OperChar S) 88 { 89 if (S.top == S.base) 90 { 91 exit(1); 92 93 } 94 return *(S.top - 1); 95 } 96 float GetTopNum(NumberLink S) 97 { 98 if (S.top == S.base) 99 { 100 exit(1); 101 102 } 103 return *(S.top - 1); 104 } 105 //将操作符转化为优先级数组的下标 106 int Change(char Oper) 107 { 108 switch (Oper) 109 { 110 case \'+\': return 0; break; 111 case \'-\': return 1; break; 112 case \'*\': return 2; break; 113 case \'/\': return 3; break; 114 case \'(\': return 4; break; 115 case \')\': return 5; break; 116 case \'=\': return 6; break; 117 default: return 6; break; 118 119 } 120 } 121 //返回优先级的大小 122 char Precede(char Oper, char ch) 123 { 124 return prior[Change(Oper)][Change(ch)]; 125 } 126 //计算两个数的结果 127 float Operate(float first,char oper1, float second) 128 { 129 switch (oper1) 130 { 131 case \'+\': 132 { 133 return (first + second); 134 break; 135 } 136 case \'-\': 137 { 138 return (first - second); 139 break; 140 } 141 case \'*\': 142 { 143 return (first * second); 144 break; 145 } 146 case \'/\': 147 { 148 if (second == 0) 149 { 150 IsRep = 1; 151 return 0; 152 } 153 return (first / second); 154 break; 155 156 } 157 default: return 0; break; 158 } 159 } 160 //数字的个数 161 void NumberAmount() 162 { 163 Amount = 2 + rand() % 5; 164 } 165 //加左括号 随机选择在第几个数字前面加括号 166 void AddLbracket(){ 167 for (int j = 0; j < 2; j++) 168 LBraket[j] = 0; 169 if (Amount == 2) 170 { 171 BracketNum = 0; 172 } 173 if (Amount == 3){ 174 BracketNum = rand() % 2; 175 } 176 if (Amount > 3) 177 { 178 BracketNum = rand() % 3; 179 } 180 for (int i = 0; i < BracketNum; i++){ 181 LBraket[i] = 1 + rand() % (Amount-2); 182 } 183 } 184 //加右括号 185 void AddRbracket(){ 186 for (int j = 0; j < 2; j++) 187 RBraket[j] = 0; 188 int choose; 189 int trance; 190 if (BracketNum == 1){ 191 RBraket[0] = LBraket[0] + 1 + rand() % (Amount - LBraket[0]); 192 } 193 if (BracketNum == 2) 194 195 { 196 //把最左边的左括号放在第一个数组中 197 if (LBraket[0] < LBraket[1]) 198 { 199 trance = LBraket[0]; 200 LBraket[0] = LBraket[1]; 201 LBraket[1] = trance; 202 } 203 //当两个左括号之间相差有点远时有2中右括号添加方法 204 if (LBraket[0] - LBraket[1]>2){ 205 choose = rand() % 2; 206 if (choose == 0){ 207 RBraket[0] = LBraket[0] + 1 + rand() % (Amount - LBraket[0]); 208 RBraket[1] = LBraket[0] + 1 + rand() % (Amount - LBraket[0]); 209 } 210 if (choose == 1) 211 { 212 RBraket[0] = LBraket[0] + 1 + rand() % (Amount - LBraket[0]); 213 RBraket[1] = LBraket[1] + 1 + rand() % (LBraket[0] - 2); 214 } 215 } 216 else 217 { 218 RBraket[0] = LBraket[0] + 1 + rand() % (Amount - LBraket[0]); 219 RBraket[1] = LBraket[0] + 1 + rand() % (Amount - LBraket[0]); 220 if (LBraket[0] == LBraket[1] && RBraket[0] == RBraket[1]){ 221 LBraket[0] = LBraket[1] = 0; 222 RBraket[0] = RBraket[1] = 0; 223 BracketNum = 0; 224 225 } 226 if (LBraket[1] == 1 && (RBraket[0] == Amount || RBraket[1] == Amount)) 227 { 228 LBraket[0] = LBraket[1] = 0; 229 RBraket[0] = RBraket[1] = 0; 230 BracketNum = 0; 231 } 232 233 } 234 } 235 } 236 //随机产生最简真分数 237 void Score(){ 238 int Left, Right; 239 Left = BaseNumber + rand() % (TopNumber - BaseNumber + 1); 240 Right = BaseNumber + rand() % (TopNumber - BaseNumber + 1); 241 while (Left >= Right || Left==0) 242 { 243 Left = BaseNumber + rand() % (TopNumber - BaseNumber + 1); 244 Right = BaseNumber + rand() % (TopNumber - BaseNumber + 1); 245 } 246 int max=1; 247 //求最大公约数 248 for (int i = 2; i <= Left; i++) 249 { 250 if (Left%i == 0 && Right%i == 0) 251 { 252 max = i; 253 } 254 } 255 if (max > 1) 256 { 257 Left /= max; 258 Right /= max; 259 } 260 formula << \'(\'<<Left << \'/\' << Right<<\')\'; 261 } 262 //随机生成操作符 263 void Operater() 264 { 265 int choose; 266 char op; 267 if (IsMulDlvExist == 1) 268 choose = 1 + rand() % 4; 269 else 270 choose = 1 + rand() % 2; 271 272 switch (choose) 273 { 274 case 1:{op = \'+\'; lastOp = \'+\'; break; } 275 case 2:{op = \'-\'; lastOp = \'-\'; break; } 276 case 3:{op = \'*\'; lastOp = \'*\'; break; } 277 case 4: 278 { 279 //防止连续除法产生运算误区 280 op = \'/\'; 281 if (lastOp == \'/\') 282 IsRep = 1; 283 else 284 lastOp = \'/\'; 285 break; 286 } 287 } 288 formula << op; 289 } 290 //随机生成整数 291 void Integer(){ 292 int num; 293 num = BaseNumber + rand() % (TopNumber - BaseNumber + 1); 294 formula << num; 295 } 296 //创建算式 297 void CreateNumber(){ 298 for (int k = 1; k <= Amount; k++) 299 { 300 301 for (int i = 0; i < 2; i++){ 302 if (LBraket[i] == k) 303 formula << \'(\'; 304 } 305 306 int cho; 307 cho = rand() % 2; 308 if (cho == 0四则运算网页版