程序设计之四则运算三
Posted 呼噜~呼噜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了程序设计之四则运算三相关的知识,希望对你有一定的参考价值。
这是第三次要对四则运算设计程序实现,这次需要两个人一起编程实现,经过讨论,我们认为最好在两个人的前两次设计中挑选比较适合的一个进行修改。
这次需要计算生成表达式的值并判断用户输入的值是否正确。
设计思路:
关键是对结果的计算,可以通过数据结构中的栈实现,计算括号中的内容,首先从第一个字符开始压栈,遇到左括号开始记录位置,继续压栈直到遇到第一个右括号,计算中间式子的值。
程序代码:
1 //赵承圣 2016.3.18 2 #include<iostream> 3 #include<ctime> 4 #include<string> 5 #include<sstream> 6 #include "SqStack.h" 7 using namespace std; 8 9 char ops[7] = { \'+\', \'-\', \'*\', \'/\', \'(\', \')\', \'=\' }; 10 char cmp[7][7] = { { \'>\', \'>\', \'<\', \'<\', \'<\', \'>\', \'>\' }, 11 { \'>\', \'>\', \'<\', \'<\', \'<\', \'>\', \'>\' }, 12 { \'>\', \'>\', \'>\', \'>\', \'<\', \'>\', \'>\' }, 13 { \'>\', \'>\', \'>\', \'>\', \'<\', \'>\', \'>\' }, 14 { \'<\', \'<\', \'<\', \'<\', \'<\', \'=\', \' \' }, 15 { \'>\', \'>\', \'>\', \'>\', \' \', \'>\', \'>\' }, 16 { \'<\', \'<\', \'<\', \'<\', \'<\', \' \', \'=\' } }; 17 18 bool IsOperator(char ch) 19 { 20 for (int i = 0; i < 7; i++) 21 if (ch == ops[i]) 22 return true; 23 return false; 24 } 25 char Compare(char ch1, char ch2) 26 { 27 int i, m, n; 28 char priority; 29 for (i = 0; i < 7; i++) { //找到相比较的两个运算符在比较矩阵里的相对位置 30 if (ch1 == ops[i]) 31 m = i; 32 if (ch2 == ops[i]) 33 n = i; 34 } 35 priority = cmp[m][n]; 36 return priority; 37 } 38 39 bool Compute(double x, char op, double y, double &z) 40 { 41 switch (op) { 42 case \'+\': z = x + y; 43 break; 44 case \'-\': z = x - y; 45 break; 46 case \'*\': z = x * y; 47 break; 48 case \'/\': if (fabs(y) > 1e-7) { 49 z = x / y; 50 break; 51 } 52 else 53 cout << "除数为0,出错!" << endl; 54 return false; 55 } 56 return true; 57 } 58 59 bool ExpEvaluation(char *str, double &result) 60 { 61 double a, b, v; 62 char ch, op; 63 int temp, i = 0; 64 SqStack <char> optr(20); //创建运算符栈optr 65 SqStack <double> opnd(20); //创建运算数栈opnd 66 optr.Push(\'=\'); 67 ch = str[i++]; 68 while (ch != \'=\' || optr.Top() != \'=\') { 69 while (ch == \' \') //跳过空格 70 ch = str[i++]; 71 if (IsOperator(ch)) { //是7种运算符之一 72 switch (Compare(optr.Top(), ch)) { 73 case \'<\': //栈顶运算符优先级低 74 optr.Push(ch); 75 ch = str[i++]; 76 break; 77 case \'=\': //脱括号并接收下一字符 78 optr.Pop(); 79 ch = str[i++]; 80 break; 81 case \'>\': //栈顶运算符优先级高,退栈并将运算结果入栈 82 op = optr.Top(); 83 optr.Pop(); 84 b = opnd.Top(); 85 opnd.Pop(); 86 a = opnd.Top(); 87 opnd.Pop(); 88 if (Compute(a, op, b, v)) { //计算v = a <op> b 89 opnd.Push(v); 90 break; 91 } 92 else { 93 result = 0; 94 return false; 95 } 96 } 97 } 98 else { //是数字 99 temp = ch - \'0\'; //将字符转换为十进制数 100 ch = str[i++]; 101 while (!IsOperator(ch) && ch != \' \') { 102 temp = temp * 10 + ch - \'0\'; //将逐个读入运算数的各位转化为十进制数 103 ch = str[i++]; 104 } 105 opnd.Push(temp); //数值入栈 106 } 107 } 108 result = opnd.Top(); 109 return true; 110 } 111 112 113 114 string IntToString(int & i) 115 { 116 string s; 117 stringstream ss(s); 118 ss << i; 119 return ss.str(); 120 } 121 122 123 void checkcon0(int &num,string chnum) 124 { 125 while(num!=2&&num!=4) 126 { 127 if(chnum=="否") 128 { 129 num=2; 130 } 131 else if(chnum=="是") 132 { 133 num=4; 134 } 135 else 136 { 137 cout<<"输入不合法,请重新输入: "; 138 cin>>chnum; 139 cout<<endl; 140 } 141 } 142 } 143 void checkcon1(int &num1,string chnum) 144 { 145 while(num1!=1&&num1!=0) 146 { 147 if(chnum=="否") 148 { 149 num1=1; 150 } 151 else if(chnum=="是") 152 { 153 num1=0; 154 } 155 else 156 { 157 cout<<"输入不合法,请重新输入: "; 158 cin>>chnum; 159 cout<<endl; 160 } 161 } 162 163 } 164 void check(int &num2,string chnum) 165 { 166 num2 = std::atoi(chnum.c_str() ); 167 while(num2<=0) 168 { 169 cout<<"输入不合法,请重新输入: "; 170 cin>>chnum; 171 cout<<endl; 172 num2 = std::atoi(chnum.c_str() ); 173 } 174 } 175 176 int main() 177 { 178 //数据定义部分 179 srand((int)time(NULL)); 180 int control[2],itemnum, num_max, num_min, num_num, bracket_num; 181 string chnum[5]; 182 string express = ""; 183 char symbol[4],c[20];; //随机计算符号数组 184 symbol[0] = \'+\'; 185 symbol[1] = \'-\'; 186 symbol[2] = \'*\'; 187 symbol[3] = \'/\'; 188 189 //输入及判断部分 190 cout << "是否有乘除(是/否): "; 191 cin >> chnum[0]; 192 checkcon0(control[0],chnum[0]); 193 cout << "是否有括号(是/否): "; 194 cin >> chnum[1]; 195 checkcon1(control[1],chnum[1]); 196 cout << "数字最大取值: "; 197 cin >> chnum[2]; 198 check(num_max,chnum[2]); 199 cout << "数字最小取值: "; 200 cin >> chnum[3]; 201 check(num_min,chnum[3]); 202 cout<<"式子数量: "; 203 cin>>chnum[4]; 204 check(itemnum,chnum[4]); 205 206 string *item=new string[itemnum]; 207 double *result = new double[itemnum]; 208 double *uans = new double[itemnum]; 209 int rightnum = 0; 210 211 //算式生成部分 212 for (int count = 0; count<itemnum; count++) 213 { 214 num_num = rand() % 10; 215 string *str = new string[num_num]; 216 if (num_num == 0 || num_num == 1) 217 { 218 count--; 219 continue; 220 } 221 222 //定义并初始化动态数组 num:数字数组 symnum:符号选择数组 sym:符号数组 223 int *num = new int[num_num]; 224 int *symnum = new int[num_num - 1]; 225 char *sym = new char[num_num - 1]; 226 227 int bracket_leftposition, bracket_rightposition; 228 int *bracket_left_time = new int[num_num]; //定义左、右括号生成次数数组,下标为数字位置 229 int *bracket_right_time = new int[num_num]; 230 string *bracket_left = new string[num_num](); //定义左右括号字符串型数组 231 string *bracket_right = new string[num_num](); 232 for (int rcount = 0; rcount<num_num; rcount++) //左、右括号生成次数初始化 233 { 234 bracket_left_time[rcount] = 0; 235 bracket_right_time[rcount] = 0; 236 } 237 238 //给参与计算的数赋值(指定数值范围) 239 for (int cnum = 0; cnum<num_num; cnum++) 240 { 241 num[cnum] = rand() % (num_max - num_min + 1) + num_min; 242 } 243 244 //随机生成式子的各个位置的符号 245 for (int snum = 0; snum<num_num - 1; snum++) 246 { 247 symnum[snum] = rand() % control[0]; 248 sym[snum] = symbol[symnum[snum]]; 249 } 250 251 252 if (control[1] == 0) 253 { 254 bracket_num = rand() % 7 + 1; 255 //生成括号次数 256 for (int bcount = 0; bcount<bracket_num; bcount++) 257 { 258 bracket_leftposition = rand() % num_num; //随机生成左右括号的位置 259 bracket_rightposition = rand() % num_num; 260 if ((bracket_leftposition >= bracket_rightposition)||((bracket_leftposition==0)&&(bracket_rightposition==num_num-1))) //先剔除部分一次性在一个数左右同时生成左右括号和在整个式子前后生成式子的情况 261 { 262 continue; 263 } 264 bracket_left_time[bracket_leftposition]++; //该位置数左括号生成次数+1 265 bracket_right_time[bracket_rightposition]++; 266 } 267 } 268 for (int stnum = 0; stnum < num_num-2; stnum++) 269 { 270 if ((symbol[symnum[stnum]] == \'/\') && (symbol[symnum[stnum + 1]] == \'/\')) 271 { 272 bracket_left_time[stnum]++; 273 bracket_right_time[stnum + 1]++; 274 } 275 } 276 for (int snum = 0; snum < num_num ; snum++) 277 { 278 279 if (bracket_left_time[snum] == 1) 280 { 281 bracket_left[snum] = "("; 282 } 283 if (bracket_left_time[snum] == 2) 284 { 285 bracket_left[snum] = "(("; 286 } 287 if (bracket_left_time[snum] == 3) 288 { 289 bracket_left[snum] = "((("; 290 } 291 if (bracket_right_time[snum] == 1) 292 { 293 bracket_right[snum] = ")"; 294 } 295 if (bracket_right_time[snum] == 2) 296 { 297 bracket_right[snum] = "))"; 298 } 299 if (bracket_right_time[snum] == 3) 300 { 301 bracket_right[snum] = ")))"; 302 } 303 for (int bpcount = 0; bpcount<num_num; bpcount++) //再次扫描数字左右括号生成次数相等的情况并排除 304 { 305 if (bracket_left_time[bpcount] == bracket_right_time[bpcount]) 306 { 307 bracket_right[bpcount] = ""; 308 bracket_left[bpcount] = ""; 309 } 310以上是关于程序设计之四则运算三的主要内容,如果未能解决你的问题,请参考以下文章