题目
如下图:
分析
利用栈的思想:
具体思路见程序实现,详细注释!
程序实现
#include <iostream>
#include <cstdlib>
#include <string>
#include <stack>
using namespace std;
int getLen(string str)
{
if (str.empty())
return 0;
stack<char> s;
int n = str.size();
if (n > 100)
{
return -1;
}
//count用于记录当前左括号的个数
int count = 0;
//记录字符串实际长度
int len = 0;
for (int i = 0; i < n; i++)
{
//(1)如果是左括号直接入栈
if (str[i] == '(')
{
s.push(str[i]);
count++;
}//if
//(2)如果是右括号,根据当前左括号的个数,分情况处理
else if(str[i] == ')'){
//栈中已有多于1个左括号,将最内层括号内元素,翻倍存储
if (count > 1)
{
string st;
//右括号外,整数值,即最内层括号内元素翻倍数
int c = str[i + 1] - '0';
while (s.top() != '(')
{
if ((s.top() - '0') >= 2 && (s.top() - '0') <= 9)
{
char num = s.top();
s.pop();
char ch = s.top();
s.pop();
//将字母和数字翻倍c次,记录
for (int k = 0; k < c; k++)
{
st += num;
st += ch;
}//for
}
else{
//单字母,记录其以及右括号外数字
st += str[i + 1];
st += s.top();
s.pop();
}
}//while
//弹出最内层左括号
s.pop();
//将临时记录翻倍元素,重新入栈
st += ' ';
int sl = strlen(st.c_str());
for (int i = sl-1; i>=0 ; i--)
{
s.push(st[i]);
}//for
//左括号个数-1
count--;
//跳过右括号后面的数字
i++;
}
//若现在只有一个左括号,直接计算长度
else if (count == 1){
int tmp = 0;
while (s.top() != '(')
{
if ((s.top() - '0') >= 2 && (s.top() - '0') <= 9)
{
tmp += s.top() - '0';
s.pop();
s.pop();
}
else{
tmp += 1;
s.pop();
}
}//while
//弹出左括号
s.pop();
len += tmp * (str[i+1] - '0');
//跳过右括号后面的数字
i++;
//左括号个数-1
count--;
}//else
}//else
//(3)如果是字母,直接入栈
else if (str[i] >= 'A' && str[i] <= 'Z')
{
s.push(str[i]);
}
//(4)如果是数字,根据当前左括号个数处理
else if ((str[i] - '0') > 1 && (str[i]-'0') <= 9)
{
//当前左括号个数大于0,则入栈
if (count > 0)
s.push(str[i]);
//当前无左括号,则计算长度
else{
len = len + (str[i] - '0');
//弹出当前字符
s.pop();
}
}//else
}
//栈中最后留下的是出现在第一个左括号之前的单字母,直接加上栈的长度
len = len + s.size();
return len;
}
int main()
{
int n;
cin >> n;
if (n <= 100)
{
for (int i = 0; i < n; i++)
{
string str;
cin >> str;
cout << getLen(str) << endl;
}//for
}//if
system("pause");
return 0;
}