7-2 括号字符串的移位操作 (20 分)
由相同数量的左括号’(‘和右括号’)'构成的字符串,只需要将一定长度(可以为0)的前缀移动到字符串的末尾,就可以使其中的左右括号匹配成功,即成为括号语句。在这里,我们不用数学方法去证明该命题的正确性,而是编程求出所有可行的前缀长度。
输入格式:
输入在一行中给出由’(‘和’)'构成的字符串,长度不超过10 6 。
题目保证字符串中左右括号的数量相同。
输出格式:
在一行中输出所有可行的前缀长度,按升序排列。数值间用空格分开,末尾的值后面没有空格。
输入样例:
(()))))()(())((()))()(((
输出样例:
7 9 13 19 21
注:上述长度的前缀各自移动到末尾后得到的括号语句如下:
长度7: ()(())((()))()((((()))))
长度9: (())((()))()((((()))))()
长度13:((()))()((((()))))()(())
长度19:()((((()))))()(())((()))
长度21:((((()))))()(())((()))()
解答
想要求出需要移动的长度,只需找出最坏情况,即缺少左括号的右括号数最大时,这些括号是必须移到后面去的。而已经配对好的括号是不影响其他括号配对的,即可移的括号为所有缺少左括号的右括号和已经配对好的括号。
#include<iostream>
using namespace std;
int main(){
string s;
getline(cin,s);
int i,max=0,len=s.size();
int num[len+2];
num[0]=0;
for(i=0;i<len;i++){
if(s[i]=='('){
num[i+1]=num[i]-1;
}
if(s[i]==')'){
num[i+1]=num[i]+1;
}
if(num[i]>max)
max=num[i];
}
int times=0;
for(i=0;i<len;i++){
if(num[i]==max){
if(times!=0){
cout<<" "<<i;
}
else
cout<<i;
times++;
}
}
return 0;
}