2 条题解

  • 2
    @ 2023-11-1 19:06:39

    可以将这个字符串从左往右写,一旦遇到匹配上的括号,就把这对括号擦掉,就像“消消乐”一样。 以[([])[]]为例,从左往右写,写到[([],产生了匹配,所以把[]擦掉,纸上的字符串变成了[(,接着写,下一个字符是),字符串编程[(),产生了匹配。擦掉(),纸上只剩下了一个[。接下来,往后写一个字符,变成[[,没有产生匹配。再写一个变为[[],擦掉[],纸上又只剩下一个[。接下来写],产生了匹配,擦掉[]之后纸上什么也不剩了。因此所给字符串是合法的。

    如果处理字符串的所有字符,发现纸上还剩有括号,那么就说明有些括号没有被匹配到,说明是非法的括号序列,比如([)(])根据上面的做法就可以知道是非法的。

    我们可以把写一个字符视为入栈,把括号匹配视为栈顶元素出栈,从而使用栈的两个操作来完成模拟的过程。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=10005;
    string s;
    char sta[N];
    int l,top;
    int main(){
        int T;cin>>T;
        while (T--){
    		cin>>s;
    		top=0;
    		l=s.size();
    		for (int i=0;i<l;++i){
    			if (s[i]==')' && sta[top]=='(') --top;
    			else if (s[i]==']' && sta[top]=='[') --top;
    			else sta[++top]=s[i];
    		}
    		if (top) cout<<"No\n";
    		else cout<<"Yes\n"; 
        }
    }
    
    
    • 0
      @ 2024-4-6 9:27:34

      括号序列匹配是栈的经典题了。题解里有用手搓栈做的,那我就提供一个用STL栈做的吧。

      原理可以看其他的题解,我这里就提供一个做法。

      我们从左到右依次扫描括号序列:

      • 如果它是([,我们就把它加入栈中。
      • 如果它是)],我们就判断:
        • 如果栈顶是当前扫描到的右括号对应的左括号,我们就将栈顶的左括号弹出。
        • 否则说明当前扫描到的右括号无法正确匹配前面的左括号,我们就退出循环并输出No

      循环结束后如果没有发现非法的括号,我们就输出Yes

      AC code:

      #include<bits/stdc++.h>
      #define ll long long
      using namespace std;
      ll n;
      int main(){
          scanf("%lld",&n);
          for(ll i=1;i<=n;i++){
              string s;
              stack<char> sta;
              bool flag=1;
              cin>>s;
              for(ll i=0;i<s.length();i++){
                  if(s[i]=='('||s[i]=='[')
                      sta.push(s[i]);
                  else if(s[i]==')')
                      if(!sta.empty()&&sta.top()=='(') // 要记得加上!sta.empty(),否则会RE
                          sta.pop();
                      else{
                          flag=0;
                          break;
                      }
                  else
                      if(!sta.empty()&&sta.top()=='[') // 要记得加上!sta.empty(),否则会RE
                          sta.pop();
                      else{
                          flag=0;
                          break;
                      }
              }
              if(flag)
                  puts("Yes");
              else
                  puts("No");
          }
          return 0;
      }
      
      • 1

      信息

      ID
      535
      时间
      1000ms
      内存
      256MiB
      难度
      5
      标签
      (无)
      递交数
      194
      已通过
      76
      上传者