1. 程式人生 > >括號匹配一道題

括號匹配一道題

合法的括號匹配序列被定義為:

1.空串“”是合法的括號序列

2.如果“X”和“Y”是合法的序列,那麼“XY”也是一個合法的括號序列

3.如果“X”是一個合法的序列,那麼“(X)”也是一個合法的括號序列

4.每個合法的括號序列都可以由上面的規則生成

例如"", "()", "()()()", "(()())","(((())))"都是合法的。現有一個合法的括號序列s,一次移除操作分為兩步:

1. 移除序列s中第一個左括號

2.移除序列s中任意一個右括號,保證操作後s依舊合法

現想知道多少種方案可以把序列s變為空

如果兩個方案中有意思移除操作移除的是不同的右括號即視為不同方案

例如:s="()()()"輸出1,因為每次都只能選擇被移除的左括號相鄰的右括號

s="(((())))",輸出24,第一次有4種情況,第二次有3種情況...,依次類推,4*3*2*1=24

輸入描述:一行,一個合法的括號序列s,長度length(2<=length<=20))

輸出描述:一個整數,表示方案數

示例:

輸入:

(((())))

輸出:

24

思路:從樣例中考慮右括號到左括號之間的右括號數目,記錄下第k個右括號到第k個左括號之間有多少個右括號(包括第k個右括號本身),最後所有數目相乘得到結果

程式碼:

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <iostream>


using namespace std;

int main(){
string s;
cin>>s;
vector<int> count_left;
vector<int> count_right;
for(int i=0; i<s.size(); i++){
if(s.at(i)=='(')
count_left.push_back(i);
else
count_right.push_back(i);
}


vector<int> multi_nums;
for(int i=0; i<count_left.size(); i++){
int this_num = 1;
int begin_idx = count_left.at(i);
int end_idx = count_right.at(i);
for(int j=begin_idx+1; j<end_idx; j++){
if(s.at(j)==')')
this_num++;
}
multi_nums.push_back(this_num);
}
int result = 1;
for(int i=0; i<multi_nums.size(); i++)
result *= multi_nums.at(i);
cout<<result<<endl;
system("pause");
return 0;
}