【问题标题】:Subsequence of a string字符串的子序列
【发布时间】:2011-10-04 22:17:55
【问题描述】:

我必须编写一个程序,它接受字符串参数 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

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

(回应迭戈塞维利亚):

按照您的建议:

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;
}
}

【问题讨论】:

  • 独特的子序列?例如,给 abacd 举例
  • dcb 是有效序列还是必须与字符串参数的给定顺序相对应?
  • @Max: aba、abc、abd、bac、bad 等。我想问题的描述不是很解释,但这就是我所拥有的。
  • 你确定你说的是子序列而不是子集?子序列只能包含连续的字母。

标签: java recursion


【解决方案1】:
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";
}

【讨论】:

    【解决方案2】:

    问题恰恰是这样的:

    给定一个有序的集 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|>=|S'|。

    • 假设/断言集合 S 的大小,|S| is >= 子集的大小,|S'|
    • 如果 |S| - |S'| = d,那么你知道每个子集 S' 都以 Si 处的数字开头,其中 0

    例如给定 S:{a, b, d, c} 和 |S'| = 3

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

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

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

    【讨论】:

      【解决方案3】:

      所以,我看到你想实现一个方法:subSequence(s, n):它返回来自s 长度为n 的所有字符字符组合 的集合,这样可以保留顺序。

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

      想一想这个问题,您正在获取字符位置的所有组合,这些组合可以表示为位数组(也称为标志)。因此,s="abcd"n=3(如您的示例),所有组合都可以表示如下:

      1110 = abc
      1101 = abd
      1011 = acd
      0111 = bcd
      

      请注意,我们从一个位域开始,其中所有字符都“打开”,然后将“关闭”位移动 1。在n &lt; length(s) - 1 的示例中事情变得有趣了。例如,说s="abcd"n=2。然后我们有:

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

      当您分析位域的子集时,递归开始发挥作用。因此,递归调用会减少位域的大小和“自下而上”的三个标志:

      100
      010
      001
      

      大部分工作是使用递归方法来查找所有位域。拥有它们后,每个位的位置都可以用作字符数组(即s)中的索引。

      这应该足以让您开始编写一些伪代码!

      【讨论】:

      • 在他的一些 cmets 之后,我意识到他确实关心子字符串的顺序......所以这个解决方案不是他想要的......我编辑了我的答案,因为
      【解决方案4】:

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

      subSequence(string, substr_length)
      

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

      1. 从一个空的子字符串集开始,我们称之为 SSet。
      2. 从 0 到字符串长度减去 substr_length 进行循环
      3. 在每个循环位置 i,您将 string[i] 作为开始字符,递归调用 subSequence(string[i+1..length], substr_length - 1)(这里的 .. 暗示了字符串的索引范围,所以你必须使用这些索引创建子字符串)。对subSequence 的递归调用将返回所有大小为substr_length -1 的字符串。您必须在所有这些子字符串前面加上您选择的字符(在本例中为 string[i]),并将它们全部添加到 SSet 集中。
      4. 只需返回构造的 SSet。这将包含所有子字符串。

      当然,这个过程是高度可优化的(例如使用动态编程存储所有长度为 i 的子字符串),但你明白了。

      【讨论】:

      • 我尝试制作某种伪代码 - 请参阅我帖子的更新。
      • @Nath,这可以显示它将如何执行,但它不是伪代码(例如,你不显示递归调用)。
      • 是的,你是对的。由于我无法制作伪代码,我决定从头开始,然后根据这一系列步骤尝试编写伪代码。
      • 对于迟到的回复,我深表歉意。我已经更新了我的原始帖子以尝试您的建议,但我仍然缺少详细信息。可以看看更新吗?
      • @Nath,在您作为我的建议显示的代码中,SSet 实际上是一个字符串集,而不是字符串。它实际上是您将在每个步骤中返回的字符串集。尝试将 SSet 视为一个集合,看看在实现中这对您是否更有意义。
      猜你喜欢
      • 1970-01-01
      • 2011-04-10
      • 2023-03-28
      • 2014-12-04
      • 1970-01-01
      • 1970-01-01
      • 2016-01-12
      • 1970-01-01
      • 2020-07-06
      相关资源
      最近更新 更多