找到最长的公共前缀?

时间:2011-11-07 07:12:11

标签: java

用两个字符串:

  “玛丽有一只小羊羔”“”玛丽有一只大羔羊“

应该返回

  

“玛丽有一个”

11 个答案:

答案 0 :(得分:27)

您不需要使用StringBuilder - 只需返回子字符串:

public String greatestCommonPrefix(String a, String b) {
    int minLength = Math.min(a.length(), b.length());
    for (int i = 0; i < minLength; i++) {
        if (a.charAt(i) != b.charAt(i)) {
            return a.substring(0, i);
        }
    }
    return a.substring(0, minLength);
}

答案 1 :(得分:3)

Apache Commons to rescue!

org.apache.commons.lang3.StringUtils.getCommonPrefix

...并将source code与dyross的巧妙/英勇的努力进行比较(目前投票率最高)。但她/他的代码虽然很好,却只能处理两个String。这可以处理任何数字。

除了不重新发明轮子之外,我还能想到为什么使用Apache Commons总是最适合这种事情的两个原因。

  1. 可以指望Apache工程师开发出经过全面测试的代码来处理任何陷阱
  2. 这意味着您不会使用stoopid实用程序方法来混淆您漂亮的代码。相反,你可以继续使用这些有趣的东西。
  3. 如果整个给定的Apache Commons模块对你的上下文来说真的太多了(它们通常只有几KB,但还可以)你可以从源代码中提取你需要的位(假设这符合许可证)。在这种情况下,indexOfDifference是一项基本功能......

答案 2 :(得分:1)

public class Test{
 public static void main(String[] args){
    String s1 = "Mary Had a Little Lamb";
    String s2 = "Mary Had a Big Lamb";
    int minStrLen = s1.length();
    if ( minStrLen > s2.length()){
        minStrLen = s2.length();
    }

    StringBuilder output = new StringBuilder();
    for(int i=0; i<minStrLen; i++){
        if ( s1.charAt(i) ==  s2.charAt(i)){
         output.append(s1.charAt(i));
        }else{
          break;
        }
    }       
    System.out.println(output.toString());
  }
}

这可能不是最佳解决方案,但这很容易理解和编程。

我从merge-sort算法的列表合并技术中借鉴了这个想法。如果您对列表合并技术一无所知,您将更好地理解我的算法的逻辑。

答案 3 :(得分:1)

String str1;
String str2;
// assuming str1.length > str2.length
  1. a.startsWith(b)== true 如果没有
  2. 在循环中继续从str1删除最后一个字符并重复检查第1步。

答案 4 :(得分:1)

此解决方案适用于多字符串数组。当你有3或4个字符串时,最好使用StringBuilder。对于2个字符串,可以使用子字符串。 C#中的代码:

    public string LongestCommonPrefix(string[] strs) {
    if(strs.Length == 0) return string.Empty;

    Array.Sort(strs);

    var first = strs[0];
    var last = strs[strs.Length - 1];

    var sb = new StringBuilder();
    for(int i = 0; i< first.Length; i++)
    {
        if(first[i] != last[i])
        {
            break;
        }
        sb.Append(first[i]);
    }

    return sb.ToString();
}

答案 5 :(得分:1)

一个非常简单的解决方案可以是:

  public static String longestCommonPrefix(String[] strs) {
    if (strs.length == 0) {
        return "";
    }
    String result = strs[0];
    for (int i = 1; i < strs.length; i++) {
        while (!strs[i].startsWith(result)) {
            result = result.substring(0, result.length() - 1);
        }
    }
    return result;
}

答案 6 :(得分:0)

我已经编写了示例代码。希望对您有帮助。下面是代码。

import java.util.Arrays;
import java.util.Collections;

public class MaxPrefixString {    

 public static void main(String[] args) {

  int count = 0;

  String [] input= {"Java is a Programming Language",
                    "Java is a OO",
                    "Java is a Platform independent language",
                    "Java is a my favourite"};

  Collections.sort(Arrays.asList(input));  
  Integer [] length = new Integer[input.length];

  for(int j= 0; j<input.length ; j++){
   length[j] = input[j].length();
  }
  Collections.sort(Arrays.asList(length));

  for(int i=0;i<length[0];i++){

   if(isValidPrefix(input[0].substring(0, i), input)){
    count++;
   }else{
    break;
   }
  }
  System.out.println("Answer:"+input[0].substring(0, count-1));
 }

 private static boolean isValidPrefix(String str,String []input){
  boolean istrueForAll = true;

  for(int i = 0;i<input.length;i++){
   istrueForAll = istrueForAll && check(input[i], str);
  }
  return istrueForAll;
 }

 private static boolean check(String input,String str){
  return input.contains(str);
 }
}

让我知道是否错过了任何情况。 click here

答案 7 :(得分:0)

效率极低,可能会受到很多批评。但是我想出了这个主意,令人惊讶的是它满足了我所有的测试用例。它甚至完成了您打算做的工作。容易明白。请对此发表评论,让我知道我可以如何改进它。 (欢迎各种评论和改进)

public struct Channel {
    public var level: UInt8 = 0
    public var isEnabled: Bool = false
    public var isSelected: Bool = false

    public init() {}
}

public final class Universe {
    var channels = [Channel](repeating: Channel(), count: 512)

    public func setLevel(_ level: UInt8, forChannel index: Int){
        channels[index].level = level
    }

    public func setLevels(_ newVal: UInt8, forChannels selections: [Bool], array oldArray: [UInt8]) -> [Channel] {
        let newArray = zip(oldArray, selections).map {
            (oldVal, flag) in flag ? newVal : oldVal

        }
        return channels[index].level = newArray //here’s where I’m stuck
    }
}

答案 8 :(得分:0)

运行时间:2 毫秒,比最长公共前缀的 Java 在线提交快 35.59%。内存使用:37.2 MB,不到最长公共前缀的 Java 在线提交的 62.51%。 注意:与手动排序相比,Arrays.sort() 会占用一些额外的毫秒!

    public String longestCommonPrefix(String[] strs) {
    
    if (strs.length == 0) {
        return "";
    }
    
    if (strs.length == 1) {
        return strs[0];
    }
    
    int minLen = Integer.MAX_VALUE;
    
    for ( int i = 0; i < strs.length; ++i ) {
        
        minLen = Math.min(minLen, strs[i].length());
    }
    
    int maxLen = 0;
    
    for (int i = minLen; i >= 0; --i)  {
        
        boolean areAllStringsHasSamePrefix = true;
        String prefix = strs[0].substring(0, i);
        
        for ( int j = 0; j < strs.length; ++j) {
        
            if ( !strs[j].startsWith(prefix) ) {
                areAllStringsHasSamePrefix = false;
                break;
            }
        }
        
        if ( areAllStringsHasSamePrefix ) {
            maxLen = Math.max(maxLen, i);
        }
    }
    
    return strs[0].substring(0, maxLen);
    
}

答案 9 :(得分:0)

简单来说,使用 org.apache.commons.lang3:

  1. 添加依赖项:
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.12.0'
  1. 编写代码:
String a = "";
String b = "";
String prefix = StringUtils.getCommonPrefix(a, b);

来自 doc 的示例,但注意到在最新版本中您不需要将字符串包装在数组中,因为现在它需要 Varargs:

 StringUtils.getCommonPrefix(null) = ""
 StringUtils.getCommonPrefix(new String[] {}) = ""
 StringUtils.getCommonPrefix(new String[] {"abc"}) = "abc"
 StringUtils.getCommonPrefix(new String[] {null, null}) = ""
 StringUtils.getCommonPrefix(new String[] {"", ""}) = ""
 StringUtils.getCommonPrefix(new String[] {"", null}) = ""
 StringUtils.getCommonPrefix(new String[] {"abc", null, null}) = ""
 StringUtils.getCommonPrefix(new String[] {null, null, "abc"}) = ""
 StringUtils.getCommonPrefix(new String[] {"", "abc"}) = ""
 StringUtils.getCommonPrefix(new String[] {"abc", ""}) = ""
 StringUtils.getCommonPrefix(new String[] {"abc", "abc"}) = "abc"
 StringUtils.getCommonPrefix(new String[] {"abc", "a"}) = "a"
 StringUtils.getCommonPrefix(new String[] {"ab", "abxyz"}) = "ab"
 StringUtils.getCommonPrefix(new String[] {"abcde", "abxyz"}) = "ab"
 StringUtils.getCommonPrefix(new String[] {"abcde", "xyz"}) = ""
 StringUtils.getCommonPrefix(new String[] {"xyz", "abcde"}) = ""
 StringUtils.getCommonPrefix(new String[] {"i am a machine", "i am a robot"}) = "i am a "

答案 10 :(得分:-2)

使用二进制搜索。尝试比较整个字符串。如果它们不相等,请尝试比较第一个字符。如果它们相等,请尝试拆分字符串(substring(0, str.length()/2)。等等。