【问题标题】:Determining if two strings are a substring of a permutation of another String确定两个字符串是否是另一个字符串排列的子字符串
【发布时间】:2013-05-07 23:34:26
【问题描述】:

所以我想弄清楚两个字符串组合在一起时是否是另一个字符串排列的子字符串。

我有一个我认为是可行的解决方案,但它在一些 JUnit 测试用例中失败了,我无法访问它失败的那些。

这是我的代码和一个测试用例

String a="tommarvoloriddle";
String b="lord";
String c="voldemort";
String b= b+c; 
char[] w= a.toCharArray();
char[] k= b.toCharArray();
Arrays.sort(k);
Arrays.sort(w);
pw.println(isPermuation(w,k)?"YES":"NO");


static boolean isPermuation(char[] w, char[] k)
{
    boolean found=false;
    for(int i=0; i<k.length; i++)
    {
        for(int j=i; j<w.length; j++)
        {
            if(k[i]==w[j])
            {
                j=w.length;
                found=true;
            }
            else
                found=false;
        }
    }


    return found;
}

任何帮助它始终产生正确答案都很棒,帮助提高效率也很棒

【问题讨论】:

标签: java string algorithm permutation


【解决方案1】:

您所拥有的不是有效的解决方案。但是,您没有解释为什么您认为它可能是这样,因此很难弄清楚您的意图。我会指出,您的代码会为每个内部循环无条件更新found,因此isPermutation() 将始终返回最后一次比较的结果(这肯定不是您想要的)。

您首先对两个数组进行排序是正确的——这是一个经典的步骤,应该可以让您一次有效地评估它们。但是,然后,您使用嵌套循环而不是单次循环——您打算在这里做什么?

单程实现可能类似于:

static boolean isPermutation(char[] w, char[] k) {
  int k_idx=0;
  for(w_idx=0; w_idx < w.length; ++w_idx) {
    if(k_idx == k.length)
      return true; // all characters in k are present in w
    if( w[w_idx] > k[k_idx] )
      return false;  // found character in k not present in w
    if( w[w_idx] == k[k_idx] )
      ++k_idx;  // character from k corresponds to character from w
  }
  // any remaining characters in k are not present in w
  return k_idx == k.length;
}

【讨论】:

  • 我认为这是一个可行的解决方案,因为它适用于我生成的所有测试用例。是的,我真的对嵌套循环感到困惑,不知道我在想什么......感谢代码虽然现在它肯定更有意义
  • 那么“aaab”和“abbb”是否返回true?
【解决方案2】:

所以我们只关心两个组合字符串是否是另一个字符串排列的子集,这意味着长度实际上可以不同。假设我们有:

String a = "tommarvoloriddle";
String b = "lord";
String c = "voldemort";

char[] master = a.ToCharArray();
char[] combined = (b + c).ToCharArray();

Arrays.Sort(master);
Arrays.Sort(combined);

System.out.println(IsPermutation(master, combined) ? "YES" : "NO");

那么我们的方法是:

static boolean IsPermutation(char[] masterString, char[] combinedString)
{
    int combinedStringIndex = 0;
    int charsFound = 0;
    int result = 0;

    for (int i = 0; i < masterString.Length; ++i) {
        result = combinedString[combinedStringIndex].CompareTo(masterString[i]);
        if (result == 0) {
            charsFound++;
            combinedStringIndex++;
        }
        else if (result < 0) {
            return false;
        }
    }

    return (charsFound == combinedString.Length);
}

上述方法的作用:它开始比较两个字符串的字符。如果我们有不匹配,即当前masterString索引处的字符与当前combinedString索引处的字符不匹配,那么我们只需查看masterString的下一个字符,看看是否匹配。最后,我们计算从combinedString 匹配的字符总数,如果它们等于combinedString 中的字符总数(它的长度),那么我们已经确定它确实是一个排列masterString。如果在任何时候,masterString 中的当前字符在数值上大于combinedString 中的当前字符,那么这意味着我们将永远无法匹配当前字符,所以我们放弃了。希望对您有所帮助。

【讨论】:

  • 为了提高处理不匹配的效率,如果(combinedString[combinedStringIndex] &lt; masterString[i]),您可以返回false。 :)
【解决方案3】:

如果两个字符串是另一个字符串的排列,你应该能够做到这一点

public static boolean isPermuted(Strign s1, String s2) {
     if (s1.length() != s2.length()) return false;

     char[] chars1 = s1.toCharArray();
     char[] chars2 = s2.toCharArray();
     Arrays.sort(chars1);
     Arrays.sort(chars2);
     return Arrays.equals(chars1, chars2);
}

这意味着在排序时字符是相同的,在相同的数字。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-11
    • 2021-10-26
    • 1970-01-01
    • 2013-09-06
    • 2011-02-07
    • 2013-05-12
    相关资源
    最近更新 更多