字符串的子序列

时间:2011-07-13 23:05:52

标签: java recursion

我必须编写一个程序,它接受字符串参数s和整数参数k,并打印出长度为k的s的所有子序列。例如,如果我有

subSequence("abcd", 3);

输出应为

 abc abd acd bcd

我想指导。请不要代码!

提前致谢。

更新

我正在考虑使用这个伪代码:

Start with an empty string
Append the first letter to the string 
  Append the second letter
    Append the third letter 
    Print the so-far build substring - base case
  Return the second letter
    Append the fourth letter
    Print the substring - base case
Return the first letter
   Append the third letter
     Append the fourth letter
     Print the substring - base case
   Return third letter
Append the second letter
   Append the third letter
     Append the fourth letter
     Print the substring - base case
   Return the third letter
Return the second letter
Append the third letter
   Append the fourth letter
Return third letter
Return fourth letter
Return third letter
Return second letter
Return first letter

不同的缩进意味着在递归调用中更深入。

(回应Diego Sevilla):

根据您的建议:

private String SSet = "";
private String subSequence(String s, int substr_length){
    if(k == 0){
       return SSet;
    }
    else{
    for(int i = 0; i < substr_length; i++){
        subString += s.charAt(i);
        subSequence(s.substring(i+1), k-1);
    }
   }
    return SSet;
}
}

4 个答案:

答案 0 :(得分:1)

当您将“递归”作为标记包含在内时,我将尝试向您解释解决方案的策略。递归函数应该是您显示的函数:

subSequence(string, substr_length)

实际上返回{sub} -strings的Set。注意如何将问题划分为易于递归的子问题。每个subSequence(string,substr_length)应该:

  1. 以空子字符串集开头,我们称之为SSet。
  2. 执行从0到字符串长度减去substr_length
  3. 的循环
  4. 在每个循环位置i中,您将字符串[i]作为起始字符,以递归方式调用subSequence(string[i+1..length], substr_length - 1)(此处..意味着将索引范围转换为字符串,所以你必须使用这些索引创建子字符串)。对subSequence的递归调用将返回所有大小为substr_length -1的字符串。您必须在所有这些子字符串前面添加您选择的字符(在本例中为string [i]),并将所有字符串添加到SSet集中。
  5. 只需返回构建的SSet。这个将包含所有子串。
  6. 当然,这个过程是高度可优化的(例如使用存储长度为i的所有子串的动态编程),但是你明白了。

答案 1 :(得分:0)

所以,我发现你想要实现一个方法:subSequence(s, n):它返回长度为s的{​​{1}}的所有字符组合的集合,这样就可以保留订购。

本着您希望为您提供代码的精神,我假设您不希望使用伪代码。因此,我将以叙述的方式解释我建议的方法,将程序代码的翻译留作读者(TM)的练习。

想想这个问题,你要获得所有字符位置的组合,它们可以表示为一个位数组(a.k.a. flags)。因此,在ns="abcd"(如您的示例中)中,所有组合都可以表示如下:

n=3

注意,我们从一个位字段开始,其中所有字符都被“打开”,然后将“关闭”位移过1.在1110 = abc 1101 = abd 1011 = acd 0111 = bcd 的示例中,事情变得有趣。例如,请说n < length(s) - 1s="abcd"。然后我们有:

n=2

当您分析位字段的子集时,递归开始起作用。因此,递归调用会减小位字段的大小,并且“自下而上”会有三个标记:

1100 = ab
1001 = ad
1010 = ac
0110 = bc
0101 = bd
0011 = cd

大部分工作是查找所有位域的递归方法。一旦你拥有它们,每个位的位置可以用作字符数组中的索引(即100 010 001 )。

这应该足以让你开始使用一些伪代码!

答案 2 :(得分:0)

问题正是这样:

鉴于有序设置S:{C0,C1,C2,...,Cn},派生所有有序子集 S',其中S'的每个成员是S的成员,{S':Cj,S':Cj + 1}的相对顺序等于相对顺序{S:Ci,S:Ci + d},其中S':Cj = S:Ci和S ':Cj + 1 = S:Ci + d。 | S |&GT; = | S'|

  • 假设/断言集合S的大小,| S |是&gt; =子集的大小,| S'|
  • 如果| S | - | S'| = d,那么你知道每个子集S'以Si开头的数字开始,其中0 <1。我&lt; d。
例如,给出S:{a,b,d,c}和| S'| = 3

  • d = 1
  • S'以'a'(S:0)和'b'(S:1)开头。

所以我们看到问题实际上是解决了S子集长度为3的词汇排序排列。

  • @ d = 0:{a,b,c,d}获取长度为3的l.o.permutations
  • @ d = 1:{b,c,d}获取长度为3的l.o.permutations
  • @ d = 2:d&gt; | S | - | S'|。 STOP。

答案 3 :(得分:0)

string subSeqString() {
    string s1="hackerrank";
    string s="hhaacckkekraraannk";
    int k=0,c=0;
    int size=s1.size(); 
    for(int i=0;i<size;i++)
    {
        for(int j=k;j<s.size();j++)
        {
            if(s1[i]==s[j])
            {   
                c++;
                k++;
                break;
            }
            k++;
        }
    }
    if(c==size)
        return "YES";
    else
        return "NO";
}
相关问题