Decode String

题目:

Given an encoded string, return it's decoded string.

The encoding rule is: k[encoded_string], where the encoded_string inside the square brackets is being repeated exactly k times. Note that kis guaranteed to be a positive integer.

You may assume that the input string is always valid; No extra white spaces, square brackets are well-formed, etc.

Furthermore, you may assume that the original data does not contain any digits and that digits are only for those repeat numbers, k. For example, there won't be input like 3a or 2[4].

Examples:

s = "3[a]2[bc]", return "aaabcbc".
s = "3[a2[c]]", return "accaccacc".
s = "2[abc]3[cd]ef", return "abcabccdcdcdef".

算法:

       对于本题中的字符串,我们可以将其抽象为一幅图,用图的深度优先搜索的思想来解决这个问题。以字符串3[ab2[cd]ef]4[gh]为例,可以将其抽象为如下的图

                                          

       接着,对该图进行深度优先搜索。首先搜索到节点2[cd],返回对应的字符串cdcd。接着,将结果返回添加到父节点,形成新的节点3[abcdcd]。然后继续进行DFS,搜索到节点ef,返回对应的字符串ef,并将结果返回添加到父节点,形成新的节点3[abcdcdef]。由于节点3[abcdcdef]的父节点为根节点,计算出节点对应的字符串abcdcdefabcdcdefabcdcdef。接着对另外一条路径执行同样的DFS操作,得到最终结果abcdcdefabcdcdefabcdcdefghghghgh。

       在实际算法实现过程中,需要考虑几个重要的方面。首先,对于以字母直接开头的字符串,如abcd3[ef],只需直接获取第一个数字之前的全部字符串即可。然后对剩余的字符串执行DFS。该过程如下

    string result="";
    int cnt=0;
    int loc=0;
    if (isalpha(s[loc]))
    {
        while (isalpha(s[loc]))
        {
            result=result+s[loc];
            loc++;
        }
        if (loc<s.length())
        {
            string sub=s.substr(loc,s.length()-loc);
            result=result+DFS(sub);
        }
        return result;
    }
        接着,对于2[abc]这样的字符串,也可以直接计算出结果。首先获取出字符串前面的数字,表示后面字符串重复出现的次数。然后再提取出方括号中的字符串,计算出最后的结果。然后对剩余的字符串继续执行DFS。该过程如下

        int numloc=0;
        int num=0;
        while (isdigit(s[numloc]))
        {
            num=num*10+(s[numloc]-'0');
            numloc++;
        }
        string str="";
        for (int i=numloc+1;i<loc-1;i++)
        {
            str=str+s[i];
        }
        
        for (int i=0;i<num;i++)
            result=result+str;
        
        if (loc<s.length())
        {
            string sub=s.substr(loc,s.length()-loc);
            result=result+DFS(sub);
        }
        return result;
         最后,对于一般的情况,如3[abc2[ef]gh]4[zz]15[mn[3[ab]g]]。则需要将该字符串分为多个子字符串,为3[abc2[ef]gh],4[zz],15[mn[3[ab]g]],然后分别进行DFS深搜。该递归过程如下
        cnt=0;
	loc=0;
	for (int i=0;i<s.length();i++)
	{
		if (s[i]=='[')
			cnt++;
                if (s[i]==']')
        <span style="white-space:pre">	</span>{
            <span style="white-space:pre">		</span>cnt--;
            <span style="white-space:pre">		</span>if (cnt==0)
            <span style="white-space:pre">		</span>{
                <span style="white-space:pre">		</span>loc=i+1;
                <span style="white-space:pre">		</span>break;
           <span style="white-space:pre">		</span> }
        <span style="white-space:pre">	</span>}
   <span style="white-space:pre">	</span> }
	 string str="";
   <span style="white-space:pre">	</span> string sub2;
	 if (loc<s.length())
	 {
		sub2=s.substr(loc,s.length()-loc);
         <span style="white-space:pre">	</span>string sub1=s.substr(0,loc);
        <span style="white-space:pre">	</span>result=DFS(sub1)+DFS(sub2);
       <span style="white-space:pre">	</span> <span style="white-space:pre">	</span>return result;
	 }
         对于其中的每个子字符串,如3[abc2[ef]gh],对其进行深搜递归。先计算2[ef]gh的结果,再返回计算3[abc2[ef]gh]的结果。

         完整的算法如下

string DFS(string s)
{
    string result="";
    int cnt=0;
    int loc=0;
    if (isalpha(s[loc]))
    {
        while (isalpha(s[loc]))
        {
            result=result+s[loc];
            loc++;
        }
        if (loc<s.length())
        {
            string sub=s.substr(loc,s.length()-loc);
            result=result+DFS(sub);
        }
        return result;
    }
    
    for (int i=0;i<s.length();i++)
    {
        if (s[i]=='[')
            cnt++;
        if (s[i]==']'&&cnt==1)
        {
            loc=i+1;
            break;
        }
    }
    
    if (cnt==1)
    {
        int numloc=0;
        int num=0;
        while (isdigit(s[numloc]))
        {
            num=num*10+(s[numloc]-'0');
            numloc++;
        }
        string str="";
        for (int i=numloc+1;i<loc-1;i++)
        {
            str=str+s[i];
        }
        
        for (int i=0;i<num;i++)
            result=result+str;
        
        if (loc<s.length())
        {
            string sub=s.substr(loc,s.length()-loc);
            result=result+DFS(sub);
        }
        return result;
    }
    
    cnt=0;
	loc=0;
	for (int i=0;i<s.length();i++)
	{
		if (s[i]=='[')
			cnt++;
        if (s[i]==']')
        {
            cnt--;
            if (cnt==0)
            {
                loc=i+1;
                break;
            }
        }
    }
	string str="";
    string sub2;
	if (loc<s.length())
	{
		sub2=s.substr(loc,s.length()-loc);
        string sub1=s.substr(0,loc);
        result=DFS(sub1)+DFS(sub2);
        return result;
	}
    
    else
    {
        cnt=0;
        loc=0;
        for (int i=0;i<s.length();i++)
        {
            if (s[i]=='[')
                cnt++;
            if (cnt==2)
            {
                loc=i;
                break;
            }
        }
        string str="";
        if (cnt==2)
        {
            while (isdigit(s[loc-1]))
                loc--;
            
            string sub=s.substr(loc,s.length()-loc-1);
            str=DFS(sub);
        }
        
        int numloc=0;
        int num=0;
        while (isdigit(s[numloc]))
        {
            num=num*10+(s[numloc]-'0');
            numloc++;
        }
        
        string temp="";
        for (int i=numloc+1;i<s.length();i++)
        {
            if (isdigit(s[i]) || s[i]==']')	break;
            temp=temp+s[i];
        }
        temp=temp+str;
        result="";
        for (int i=0;i<num;i++)
            result=result+temp;
        return result;

    }
	
}

string decodeString(string s)
{
	string result=DFS(s);
	return result;
}



 


       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值