确定两个字符串是否是另一个String的排列的子字符串

时间:2013-05-07 23:34:27

标签: java string algorithm permutation

所以我试图找出两个字符串组合在一起时是否是另一个字符串排列的子字符串。

我有我认为是一个有效的解决方案,但它失败了一些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;
}

任何帮助,总是能够产生正确的答案会很棒,有助于提高效率也会很棒

3 个答案:

答案 0 :(得分:3)

你拥有的不是一个有效的解决方案。但是,你没有解释为什么你认为它可能是,所以很难弄清楚你的意图。我将指出您的代码无条件地为每个内部循环更新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;
}

答案 1 :(得分: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中的当前字符,则表示我们永远无法匹配当前字符,因此我们放弃了。希望有所帮助。

答案 2 :(得分:0)

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

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

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