一、括号匹配
1.输入一组字符,通过函数判断括号是否匹配,这样可以大大提高工作效率。
这个函数的作用很大,使用的方面也很多,在Vs中就有这样的功能,当你写代码时,当代码中的括号不匹配时,就会出现下划线,这样就省去了我们自己去找的时间。
2.函数的实现:
(1)应对 ( , ) , < , > , [ , ] , { , } 这些主要的符号进行处理
(2)获取一个字符串用循环语句,一个接一个查看字符,当字符不是 ( , ) , < , > , [ , ] , { , } 时,不处理
(3)当获取的字符为 ( ,<,{,[ 时存入栈中;当获取的字符为 ),> ,},] 时让栈顶元素并与当前字符判断,当能构成 (),[ ] ,{ } 时,出栈一次,当栈为空--->右括号多了,当不匹配时--->括号次序不对,当字符取完时栈不为空---->左括号多了
(4)当字符取完时,栈也为空---->括号匹配
3.函数代码
#include<stack> //2.括号匹配
bool MatchBrackets(char* pStr)
{
if (pStr == NULL)
return true;
stack<char> s;
int len = strlen(pStr);
for (int i = 0; i < len; i++)
{
if (pStr[i] != '(' && pStr[i] != ')' &&
pStr[i] != '[' && pStr[i] != ']' &&
pStr[i] != '{' && pStr[i] != '}')
continue;
else
{
if (pStr[i] == '(' || pStr[i] == '[' || pStr[i] == '{')
s.push(pStr[i]);
if (pStr[i] == ')' || pStr[i] == ']' || pStr[i] == '}')
{
if (s.empty())
{
cout << "右括号多" << endl;
return false;
}
if ((s.top()=='('&&pStr[i]==')')||(s.top()=='['&&pStr[i]==']')||(s.top()=='{'&&pStr[i]=='}'))
s.pop();
else
{
cout << "次序错误" << endl;
return false;
}
}
}
}
if (!s.empty())
{
cout << "左括号多" << endl;
return false;
}
else
return true;
}
测试
int main()
{
char *p = "(()]"; //括号不匹配
/*char*p = "()()()("; //左括号多
char*p = "()()(()))"; //右括号多了
char*p = "(){}[]";*/ //括号不匹配
bool ret=MatchBrackets(p);
cout << ret << endl;
system("pause");
return 0;
}
这里就完成了一个简单的括号匹配函数
二、逆波兰表达式
1.逆波兰表达式也称后缀表达式
2.在我们写一个算式时,一般都会写成 12x(3+4)-6+8/2 这个是中缀表达式。
将这个中缀表达式改成后缀表达式则为 12 3 4 - * 6 - 8 2 / +
3.给出一个后缀表达式,按其格式写代码求出其值
enum OPERATOR //3.简易版后缀表达式的实现
{
ADD,
SUB,
MUL,
DIV,
DATA
};
struct Cell
{
OPERATOR _op;
int data;
};
int CalcRPN(Cell* p, int size)
{
stack<int> s;
for (int i = 0; i < size; i++)
{
if (DATA == p[i]._op)
s.push(p[i].data);
else
{
int right = s.top();
s.pop();
int left = s.top();
s.pop();
switch (p[i]._op)
{
case ADD:
s.push(left + right);
break;
case SUB:
s.push(left - right);
break;
case MUL:
s.push(left*right);
break;
case DIV:
s.push(left / right);
break;
default:
break;
}
}
}
return s.top();
}
int main()
{
Cell RPN[] = { { DATA, 12 }, { DATA, 3 }, { DATA, 4 }, { ADD, 0 }, { MUL, 0 },
{ DATA, 6 }, { SUB, 0 }, { DATA, 8 }, { DATA, 2 }, { DIV, 0 }, { ADD, 0 } };
int ret=CalcRPN(RPN, sizeof(RPN) / sizeof(Cell));
cout << ret << endl;
system("pause");
return 0;
}
4.中缀式转换成后缀式
代码实现
#include<assert.h>
bool Isoperator(const char ch)
{
if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '%' || ch == '(' || ch == ')')
return true;
return false;
}
//栈内操作符
int isp(char ch)
{
switch (ch)
{
case '#':
return 0;
case '(':
return 1;
case '*':
case '/':
case '%':
return 5;
case '+':
case '-':
return 3;
case ')':
return 6;
default:
assert(0);
cout << "运算符不合法" << endl;
}
return 0;
}
//栈外操作符
int icp(char ch)
{
switch (ch)
{
case '#':
return 0;
case '(':
return 6;
case '*':
case '/':
case '%':
return 4;
case '+':
case '-':
return 2;
case ')':
return 1;
default:
assert(0);
cout << "运算符不合法" << endl;
}
return 0;
}
void Postfixnotation(char*Expre)
{
//stack<char>Data;
string str;
char ch;
stack<char>Op;
Op.push('#');
int i = 0;
while (Expre[i])
{
if (!Isoperator(Expre[i]))
{
str.push_back(Expre[i]);
cout << Expre[i];
}
else
{
str.push_back(' ');
cout << ' ';
ch = Op.top();
if (icp(Expre[i]) > isp(ch))
Op.push(Expre[i]);
else if (icp(Expre[i]) < isp(ch))
{
str.push_back(ch);
Op.pop();
cout << ch;
continue;
}
else
{
if (Op.top() == '(')
{
Op.pop();
}
}
}
++i;
}
while (Op.top() != '#')
{
ch = Op.top();
str.push_back(ch);
cout << ch;
Op.pop();
}
cout << endl;
str.push_back(0);
}
测试函数
int main()
{
char*p = "12*(3+4)-6+8/2";
Postfixnotation(p);
system("pause");
return 0;
}
可得后缀表达式