四则运算表达式生成
为了配合上一篇博客里所写的小程序,我又写了一个能够自动生成四则运算表达式的程序。程序的总体思路比较简单,
- 随机生成一个数字,代表着生成表达式中操作数的个数。
- 循环生成一个数字,将其输出,然后等概率生成‘+’‘-’‘*’‘/’中的一个跟在该数字后面,输出。
- 以一定概率生成左括号,若生成了左括号则输出,并进行计数标志当前共有多少个未完成匹配的左括号。
- 若当前有未完成匹配的左括号,则在生成一个数字后,生成一个操作符前,以一定的概率生成右括号。
- 在生成完毕后,生成最后一个数并将为匹配的左括号予以匹配。
根据上述思路,其代码实现如下:
1 #include <bits/stdc++.h> 2 3 #define maxl 8 4 #define maxn 100 5 6 using namespace std; 7 8 typedef long long ll; 9 10 ofstream fout("equation.txt"); 11 char Op[] = {'+', '-', '*', '/'}; 12 13 void create() 14 { 15 //首先随机生成算式中操作数的个数,其数量必须大于1 16 int length; 17 do{ 18 length = rand()%maxl; 19 }while(length < 2); 20 bool div = false; //用来防止出现除0错误 21 int brack_cnt = 0; //记录未匹配的左括号个数 22 ll num, op; 23 24 for (int i = 1; i < length; i++) //循环生成算式 25 { 26 if (div) //若此时需要生成的数字前的负号是'/',则需要特判此次生成的数字不能为0 27 { 28 div = false; 29 do{ 30 num = rand()%maxn; 31 }while(num == 0); 32 fout << num; 33 } 34 else 35 fout << rand()%maxn; //否则直接生成数字输出 36 int tmpcnt = brack_cnt; 37 for (int j = 0; j < tmpcnt; j++) //若当前有未匹配的左括号,则对每一个未匹配的左括号,都有一定概率生成相应右括号。 38 { 39 if ((rand()%5) > 2) //生成右括号概率为0.6 40 { 41 brack_cnt--; 42 fout << ")"; 43 } 44 } 45 46 op = rand()%4; //生成运算符 47 fout << Op[op]; 48 if (op == 3) //若生成了除号,则需要置相应标志位 49 div = true; 50 51 if (!(rand()%3)) //以一定概率生成左括号,概率为1/3 52 { 53 fout << "("; 54 brack_cnt++; 55 fout << rand()%maxn; //生成左括号后必须生成一个数字和运算符,不然可能出现(15)这样的错误 56 op = rand()%4; 57 fout << Op[op]; 58 if (op == 3) 59 div = true; 60 } 61 } 62 if (div) //生成最后一个数字,该数字后不需要跟运算符 63 { 64 div = false; 65 do{ 66 num = rand()%maxn; 67 }while(num == 0); 68 fout << num; 69 } 70 else 71 fout << rand()%maxn; 72 while(brack_cnt--) //补全右括号 73 fout << ")"; 74 fout << endl; 75 } 76 77 int main() 78 { 79 srand(time(0)); 80 int t; 81 //获得需要生成算式的个数 82 cin >> t; 83 while(t--) 84 create(); 85 return 0; 86 }
总结
这个程序在一定程度上实现了我们所需要的功能,但是仍有一定的不足,最重要的一个问题就是会生成一些无用的括号,比如(2*3)*4等。所以整个程序还是有改进的余地的,在日后可以对其进行优化,使其能够完美的实现需求的功能。