- 问题描述:
- 检查字符串表达式中的括号是否匹配;
- 左括号数目同有括号数目不相等即为不匹配;
- 去除多余的左括号或者右括号,优先保留先出现的括号;
- 匹配后去除无效的括号:如:((表达式)) 应为(表达式);
- 只考虑小括号,不考虑先出现右括号的情况;
- 要求实现函数: (字符串最长长度为60;表达式正确性不需要考虑)
void Bracket(char* src, char* dst);
如果匹配则通过dst输出原串;
如果不匹配则根据要求去处多于括号后通过dst输出匹配后的串
输入:12+(345*25-34) 输出:12+(345*25-34)
输入:12+(345*(25-34) 输出: 12+(345*25-34)
输入:(12+345)*25)-34 输出: (12+345)*25-34
输入:(543+(256-43)*203))+24 输出:(543+(256-43)*203)+24
输入:((1+2)*((34-2))+((2*8-1) 输出:((1+2)*(34-2)+2*8-1)
我的分析思路:
该题目有点像检测代码语法错误,输入一个符合格式的字符数组,程序检查给格式的正确性。并给与改正。
算法步骤:
1 判断括号匹配(这个是栈的一个很好的运用):
扫描字符数组(程序中规定的是字符串,可以通过memcpy将他们拷贝到一个数组里面,这样好修改),如果是‘(’就入栈,当如果是‘)’,这时就要小心了:我发现有三种情况:
(1)如果栈为空,很明显,这个字符没有匹配的,判断为错误字符,用‘@’字符替代(原因后面再说)。
(2)如果栈不为空且大于1,但是这个字符串中最后一个‘)’符号。这就说明,前面出现了((????)这种局面,按照第三个条件,优先保留最前面的,所以这个和应该和栈低的那个‘(’比配。
(3)如果栈不为空且,这个字符也不是最后一个字符,说明这个和栈顶的元素匹配。
2 判断出相邻多余的括号
经过上面的筛选,我们就得到一个存匹配括号的vector,然后就可以检查他们是不是多余的括号了;经过观察,如果是多余的括号,那么他们的左右括号位置相差为1。如(左括号位置,右括号位置)(2 ,5)(3,4)。当然这种思路不会筛选出(2,4)(3,5),但是这里就这个题而言,一部的筛选已经把这种情况排出了。
下面是我的代码(为了实现简单,用了一些stl库):
void M_Bracket(char* src, char* dst)
{
int len=strlen(src);
if(len>MaxNum)//src >MaxNum
{
dst=NULL;
return;
}
bool flg=true;
vector<Pair> Pairs; //存储匹配结果
stack<Pair> bracket;
///计算出右括号的个数
int right_Bracket=0;
int recordOFDele=0;//记录删除数据的个数
int Ince=0; //
while (src[Ince]!='\0')
{
if (src[Ince]==')')
{
right_Bracket++;//
Ince++;
}else
Ince++;
}
for (int i=0;i<len;i++)
{
Pair tmp_Pair;
switch (src[i])
{
case '(':
tmp_Pair.c_char='(';
tmp_Pair.left=i;
tmp_Pair.right=0;
bracket.push(tmp_Pair);
break;
case ')':
if (right_Bracket>1&&bracket.size()>0)
{
tmp_Pair=bracket.top();
tmp_Pair.right=i;
Pairs.push_back(tmp_Pair); //存储结果
bracket.pop(); //
}
else if(right_Bracket==1&&bracket.size()>0)
{
int s_size=bracket.size();
for(int i=0;i<s_size-1;i++)//删除前面的(( 除第一个
{
tmp_Pair=bracket.top();
src[tmp_Pair.left]='@';//标记将被删除的数据
recordOFDele++;
bracket.pop();
}
tmp_Pair=bracket.top();
tmp_Pair.right=i;
Pairs.push_back(tmp_Pair);
}
else if(bracket.size()==0)//没有匹配
{
flg=false;
//删除该符号
recordOFDele++;
src[i]='@';
}
right_Bracket--;
break;
default:
break;
}
}
for (int i=0;i<Pairs.size()-1;i++)
{
if(abs(Pairs[i].right-Pairs[i+1].right)==1&&abs(Pairs[i].left-Pairs[i+1].left)==1)///这组括号中间相隔为0 及为多余的括号
{
src[Pairs[i].left]='@';
src[Pairs[i].right]='@';
recordOFDele=recordOFDele+2;
}
}
///将src复制到dst中
int j=0;
for (int i=0;src[i]!='\0';i++)
{
if (src[i]!='@')
{
dst[j]=src[i];
j++;
}
}
dst[j]='\0';
}
int _tmain(int argc, _TCHAR* argv[])
{
char src[]="((1+2)*((34-2))+((2*8-1)";
char dst[MaxNum];
M_Bracket(src,dst);
puts(dst);
return 0;
}