【发布时间】:2011-12-23 10:27:28
【问题描述】:
在两个字符串中:
“玛丽有一只小羊羔”
“玛丽有一只大羊羔”
应该返回
“玛丽有一个”
【问题讨论】:
-
这里给出的例子很容易理解,但是如果字符串是“ababac”,那我怎么能找到最长的公共前缀呢?
标签: java
在两个字符串中:
“玛丽有一只小羊羔”
“玛丽有一只大羊羔”
应该返回
“玛丽有一个”
【问题讨论】:
标签: java
您不需要使用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);
}
【讨论】:
Apache Commons 来救援!
org.apache.commons.lang3.StringUtils.getCommonPrefix
...并将source code 与 dyross 的巧妙/勇敢的努力进行比较(目前投票最高)。但是她/他的代码,虽然很好,但只处理两个Strings。这可以处理任何数字。
除了不重新发明轮子之外,我可以想到使用 Apache Commons 总是最适合这类事情的两个原因。
如果整个给定的 Apache Commons 模块对于您的上下文来说确实太多(它们通常只有几 kB,但没关系),您可以从源代码中提取您需要的位(假设这符合许可证)。在这种情况下indexOfDifference 是必不可少的功能...
【讨论】:
String str1;
String str2;
// assuming str1.length > str2.length
【讨论】:
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 或 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();
}
【讨论】:
一个非常简单的解决方案可以是:
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;
}
【讨论】:
我已经编写了一个示例代码。希望它会帮助你。下面是代码。
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
【讨论】:
一个非常没有效率,可能会受到很多批评。但我想出了这个想法,令人惊讶的是它满足了我所有的测试用例。它甚至完成了你打算做的工作。容易明白。请对它发表评论,让我知道如何改进它。 (欢迎各种评论和改进)
class Solution {
public String longestCommonPrefix(String[] strs) {
int i;
StringBuilder sb = new StringBuilder("");
if(strs.length == 0 ){
return sb.toString();
}
for(int j = 0 ; j< strs[0].length();j++)
{
int count=0;
for(String word: strs){
try{
word.charAt(j);
}catch(Exception e){
return sb.toString();
}
if(word.charAt(j) == strs[0].charAt(j) ){
count ++;
}else{
return sb.toString();
}
if(count == strs.length){
sb.append(word.charAt(j));
}
}
}
return sb.toString();
}}
【讨论】:
运行时间: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);
}
【讨论】:
简单地说,用 org.apache.commons.lang3:
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.12.0'
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 "
【讨论】:
使用二分查找。尝试比较整个字符串。如果它们不相等,请尝试比较第一个字符。如果它们相等,请尝试拆分字符串 (substring(0, str.length()/2)。等等等等。
【讨论】: