POJ3704 括号匹配问题 递归方法

目录

题目

算法

完整代码


题目

参考

递归:

https://blog.youkuaiyun.com/qq_45272251/article/details/103257953

利用了递归, 但思路稍复杂了

循环:

https://blog.youkuaiyun.com/weixin_50340097/article/details/114579805

(看起来是递归其实是循环. 每次递归其实是循环内一次迭代, 没有使用递归的精髓)

https://blog.youkuaiyun.com/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;
}

运行效果:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值