反转子串

题目:

给定一个只包含括号和小写字母的字符串S,例如S="a(bc(de)fg)hijk"。  

其中括号表示将里面的字符串翻转。(注意括号可能嵌套)

请你输出翻转之后的字符串。

Input

字符串S。

对于50%的数据,|S| ≤ 1000  

对于100%的数据, |S| ≤ 5000000

Output

输出反转后的字符串(不带括号)。

Sample Input
a(bc(de)fg)hijk
Sample Output
agfdecbhijk
思路:这里开始想着 用栈直接模拟,写完之后直接爆掉,想想这个数据量,也是,只能扫一遍处理。看到一种方法,拿一个数组记录对应括号的位置,(用栈实现),然后正序输出,如果当前遇到括号,调到括号另一边,往回加。一直加到当前括号。但是有个问题,再次到当前括号,又会跳转到对应括号,怎么跳出来呢?一个很巧妙的方法,设置一个方向标志d=1,每次遇到括号就取反,当再次回到同一个括号处时,概括内的已经处理好了,翻转2次,继续正方向输出。

#include 
using namespace std;
#define N 5000000+5
char a[N], b[N];
int c[N];
int main()
{
	cin >> a;
	int  stl;
	stl = strlen(a);
	stack s;
	memset(c, -1, sizeof(c));
	int index;
	for (int i = 0; i < stl; i++)
	{
		if (a[i] == '(' )
		{
			s.push(i);  //把左括号的下标亚栈
		}
		else if (a[i] == ')')//遇到有括号时候出栈,记录下标
		{
			index = s.top();
			c[i] = index;
			c[index] = i;
			s.pop();
		}
	}
	//for (int i = 0; i < stl; i++)
		//cout << c[i] << endl;
	int  cur = 0, d = 1, sum = 0;

	while (cur != stl)
	{
		if (a[cur] == '(' || a[cur] == ')')//a(bc)d当第二次遇到(时,d再一次反转,这次从)向右继续
		{
			cur = c[cur];
			d = -d;
			cur += d;
		}
		else
		{
			b[sum++] = a[cur];
			cur += d;
		}

	}
	b[sum] = '\0';
	cout << b << endl;

	return 0;
}



你可能感兴趣的:(字符串)