目录
题目


参考
递归:
https://blog.csdn.net/qq_45272251/article/details/103257953
利用了递归, 但思路稍复杂了
循环:
https://blog.csdn.net/weixin_50340097/article/details/114579805
(看起来是递归其实是循环. 每次递归其实是循环内一次迭代, 没有使用递归的精髓)
https://blog.csdn.net/qq_38851184/article/details/104252592
循环这篇文章的收获, 额外定义状态数组记录对应位置是否匹配.
本文利用递归栈的特性, 力求简明快速地解决这个问题.
算法
首先定义全局变量
(1)待匹配的字符串str2;
(2)定义字符数组state用来记录每个位置的匹配状态. (尚未匹配上的全部标注为$或? , 待匹配上后改回来.)
递归函数输入参数
(1)查找开始位置start
(2)未匹配左括号个数(递归栈内剩余元素)leftnum
递归函数返回值
右括号位置('0'代表无可匹配的右括号)
递归算法流程:
1.如果当前下标对应字符串是'(',记录为'$'
(1)左括号入栈: 调用递归栈从下一个位置开始寻找左括号. start=pos+1, leftnum=leftnum+1.
(2)若左括号匹配成功. 配对的左右括号记录为' '. 从已经找到的右括号右侧继续下一次循环.
(3)若左括号匹配失败, 出栈(返回匹配失败记号0). (所调用的递归已遍历到字符串结束.)
2.如果当前下标对应字符串是')',记录为'?'
(1)若栈非空(leftnum!=0), 左括号出栈: 即递归函数返回(返回值右括号位置pos).
(2)若栈空(leftnum==0): 没有左括号时,说明在递归最外层, 不返回, 继续循环.
3、如果当前下标对应的字符既不是'('也不是')',,记录为' '.
完整代码
#include <bits/stdc++.h>
using namespace std;
#define MAXN 105
 
char str2[MAXN];
char state[MAXN];
int match(int start, int leftnum){
    int right=0;
    if(start>=strlen(str2))//匹配到最后返回
        return 0;
    for(int pos=start;pos<strlen(str2);pos++){
        if(str2[pos]=='('){//情况1.出现左括号
            state[pos]='$';//记录未匹配的左括号
            right=match(pos+1,leftnum+1);
            printf("(:%d; ):%d\n",pos,right);
            if(right>0){//匹配成功
                state[pos]=' ';
                state[right]=' ';
                pos=right;//跳过上次找过的地方
            }else{//如果到最后都没有找到, 说明整个字符串都被遍历过了
                return 0;
            }
            // match(right+1,leftnum);//没有需要匹配的左括号就不入递归栈
            // break;
        }else if(str2[pos]==')'){//情况2. 出现右括号
            state[pos]='?';
            // printf("):%d\n",pos);
            // match(pos+1);//永远由左括号触发下一层递归入栈, 右括号控制出栈
            if(leftnum>0){//栈非空
                return pos;
            }
        }else{//情况3. 左右括号都不是
            state[pos]=' ';
        }
    }
    return 0;
}
 
int main()
{
    while(gets(str2))
    {
        memset(state,'\0',sizeof(state));
        match(0,0);
        puts(str2);
        puts(state);
        cout<<endl;
    }
    return 0;
}
 
运行效果:
![]()
![]()










