服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++实现四则运算器(带括号)

C++实现四则运算器(带括号)

2021-10-07 15:56shadowgully C/C++

这篇文章主要为大家详细介绍了C++实现四则运算器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了C++实现四则运算器的具体代码,供大家参考,具体内容如下

基本分析可以看另一篇文章:C++实现四则运算器(无括号)

栈的实现

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//stack.h
#ifndef STACK_H
#define STACK_H
#include<iostream>
class stack_int
{
private:
 int* bottom;   //栈底
 int* top;    //栈顶
 unsigned int capacity;//栈容量
 unsigned int size; //栈大小
public:
 stack_int() :bottom(new int[11]), top(bottom), capacity(10), size(0) {};
 stack_int(unsigned int capacity) :bottom(new int[capacity+1]),top(bottom), capacity(capacity),size(0){};
 int operator[](unsigned int i) const
 {
 return *(bottom + i);
 }
 bool isEmpty()const { return bottom == top; }
 bool isFull()const { return size == capacity-1; }
 unsigned int getsize()const { return size; }
 unsigned int getcapacity()const { return capacity; }
 int gettop()const
 {
 if (!isEmpty())
 return *(top - 1);
 else
 return -1;
 }
 void settop(int i)
 {
 if (!isEmpty())
 {
 *(top - 1) = i;
 }
 }
 void push(int i)
 {
 if ((top - bottom)<capacity)
 {
 *top = i;
 top++;
 size++;
 }
 else
 {
 std::cout << "stack full!" << std::endl;
 stack_expansion();
 push(i);
 }
 }
 int pop(int &val)
 {//返回值为1则栈未空,返回值为0则栈已空无法出栈
 if (top > bottom)
 {
 top--;
 size--;
 val = *top;
 return 1;
 }
 else
 {
 std::cout << "stack empty!" << std::endl;
 return NULL;
 }
 }
private:
 void stack_expansion()
 {//栈扩容
 std::cout << "正在扩容中..." << std::endl;
 int newcapacity = 2 * capacity + 1;
 int* newbottom = new int[newcapacity + 1];
 int* newtop = newbottom;
 for (int i = 0; i < size; ++i)
 {
 *newtop = *bottom;
 newtop++;
 bottom++;
 }
 bottom = newbottom;
 top = newtop;
 capacity = newcapacity;
 }
};
 
#endif

主程序

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
//Main.c
#include"stack.h"
#include<iostream>
using namespace std;
bool is_digit(char i)
{//是数字
 if (i == '1' || i == '2' || i == '3' || i == '4' || i == '5' || i == '6' || i == '7' || i == '8' || i == '9' || i == '0')
 return true;
 else return false;
}
bool is_operator(char i)
{//是运算符
 if (i == '+' || i == '-' || i == '*' || i == '/' || i == '(' || i == ')'||i=='=')
 return true;
 else return false;
}
bool get_priority(char pre,char cur)
{//获取两个符号间的优先级,pre为靠前的字符,cur为靠后的字符
 if ((pre == '+' || pre == '-') && (cur == '*' || cur == '/'))
 return false;
 else if (pre == '(' || cur == '(')
 return false;
 else
 return true;
}
int do_operation(int lnum, char ope, int rnum)
{
 if (ope == '+')
 return lnum + rnum;
 if (ope == '-')
 return lnum - rnum;
 if (ope == '*')
 return lnum * rnum;
 if (ope == '/')
 return lnum / rnum;
}
/*
1+2*3=
1*(2+1*(3+5)+4*3)=
先乘除,后加减,有括号先算括号内的
1+5*4-345+36/6*4+145*4*5-52=
*/
 
void do_arithmetic()
{
 stack_int s;
 stack_int num_stack;//数据栈
 stack_int ope_stack;//符号栈
 char current_char;
 current_char = getchar();
 bool overflag = false;//结束标志
 bool errorflag = false;//出错标志
 while (overflag != true)
 {//未遇到=号时不断进行四则运算
 if (is_digit(current_char))
 {//遇到数字符号则将完整的数解析出来并保存于栈中
 int num = 0;
 num = current_char - '0';//符号转数字
 current_char = getchar();//获取下一个字符
 while (is_digit(current_char))
 {
 num = num * 10 + (current_char - '0');
 current_char = getchar();
 }
 num_stack.push(num);
 //cout <<"the number is " <<num << endl;
 }
 if (current_char == ' '||current_char=='\n')
 {//空格或换行则继续
 current_char = getchar();
 continue;
 }
 if (is_operator(current_char))
 {//遇到运算符则将运算符保存于运算符栈中
 int ope = '?';
 //如果当前符号栈非空,则不断根据优先级决定是否进行一次运算
 while ((!ope_stack.isEmpty()) && (get_priority((char)ope_stack.gettop(), current_char)))
 {//如果前一个运算符优先级更高
 ope_stack.pop(ope);
 //cout << "找到了前一个运算符为: " << (char)ope << endl;
 int lnum, rnum;
 //符号栈非空时,数据栈应该至少有两个数,否则出错
 if (num_stack.isEmpty())
 {
  cout << "error: 数据栈缺失两个元素,解析失败!" << endl;
  errorflag = true;
  overflag = true;
  break;
 }
 num_stack.pop(rnum);
 if (num_stack.isEmpty())
 {
  cout << "error: 数据栈缺失一个元素,解析失败!" << endl;
  errorflag = true;
  overflag = true;
  break;
 }
 num_stack.pop(lnum);
 lnum = do_operation(lnum, (char)ope, rnum);//进行运算
 num_stack.push(lnum);
 }
 if (current_char == '=')
 {//如果解析到=号了,解析完成
 if (!ope_stack.isEmpty())
 {
  errorflag = true;
  cout << "error: 缺失)" << endl;
 }
 overflag = true;
 break;
 }
 ope_stack.push(current_char);
 if (current_char == ')')
 {//右括号则出栈两次,将右括号和匹配的左括号出栈
 ope_stack.pop(ope);
 if (ope_stack.isEmpty())
 {
  cout << "error: 没有与)相匹配的(" << endl;
  errorflag = true;
  overflag = true;
  break;
 }
 ope_stack.pop(ope);
 }
 current_char = getchar();
 }
 }
 //for (int i = 0; i < num_stack.getsize(); ++i)
 // cout << num_stack[i] << "\t";
 //cout << endl;
 //for (int i = 0; i < ope_stack.getsize(); ++i)
 // cout << (char)ope_stack[i] << "\t";
 if (!errorflag)
 cout << num_stack.gettop() << endl;
}
 
int main()
{
 cout << " ______________" << endl;
 cout << "|整数四则运算器|" << endl;
 cout << " --------------" << endl;
 cout << "功能介绍:进行整数表达式的四则运算" << endl;
 cout << "可以使用的运算符:+ - * /" << endl;
 cout << "使用方式:输入以=结尾的算数运算表达式,回车后即可得到运算结果" << endl;
 cout << endl;
 //2432+5423-534*42=
 while (true)
 {
 cout << "____________________" << endl;
 cout << "--------------------" << endl;
 cout << "> ";
 do_arithmetic();
 }
 return 0;
}

程序大部分与不带括号版本很相似,主要更改了两个方面:

1.对于左括号,令左括号左边运算符优先级低于左括号,右边运算符优先级高于左括号(即,只要含有左括号的比较结果均为无法进行运算,函数get_priority返回值永远为false)。

2.对于右括号,令右括号左边的运算符(除左括号外)优先级均高于右括号,并且当右括号左边的符号为左括号时,两个括号相抵消,左括号退栈。

遇到右括号时,两括号内的+ - * /运算全部可以进行,直到符号栈栈顶为左括号。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/weixin_43972675/article/details/107837707

延伸 · 阅读

精彩推荐