程序设计之四则运算三

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        

以上是关于程序设计之四则运算三的主要内容,如果未能解决你的问题,请参考以下文章

20165223 结对编程之四则运算

DeepID人脸识别算法之三代

日常Geetest滑动验证码(三代canvas版)处理小结(以B站登录验证为例)

四则运算

二维码生成之纠错码算法

全排列