比较两个字符串的前三个字符

时间:2010-02-14 16:08:11

标签: java

字符串s1和s2的长度始终为1或更高。

如何加快速度?

int l1 = s1.length();

if (l1 > 3) { l1 = 3; }

if (s2.startsWith(s1.substring(0,l1))) 
{
 // do something..
}

正则表达可能吗?

6 个答案:

答案 0 :(得分:6)

这似乎很合理。这对你来说真的太慢了​​吗?你确定这不是过早的优化吗?

答案 1 :(得分:6)

重写以避免对象创建

你的直觉是正确的。新对象(substring())的创建速度不是很快,这意味着每个创建的对象也必须产生g / c开销。

这可能要快得多:

static boolean fastCmp(String s1, String s2) {
    return s1.regionMatches(0, s2, 0, 3);
}

答案 2 :(得分:3)

if (s2.startsWith(s1.substring(0, Math.min(3, s1.length())) {..};
不过,它没有什么缓慢的。 startsWith具有复杂度O(n)

另一种选择是比较char值,这可能更有效:

boolean match = true;
for (int i = 0; i < Math.min(Math.min(s1.length(), 3), s2.length()); i++) {
    if (s1.charAt(i) != s2.charAt(i)) {
       match = false;
       break;
    }
}

答案 3 :(得分:2)

我的java不太好,所以我会在C#中给你一个答案:

int len = Math.Min(s1.Length, Math.Min(s2.Length, 3));
for(int i=0; i< len; ++i)
{
    if (s1[i] != s2[i])
       return false;
}
return true;

请注意,与你和Bozho不同,这不会创建一个新的字符串,这将是算法中最慢的部分。

答案 4 :(得分:0)

也许你可以这样做

if (s1.length() > 3 && s2.length() > 3 && s1.indexOf (s2.substring (0, 3)) == 0)
{
  // do something..
}

答案 5 :(得分:0)

这里缺少上下文: 你想要扫描什么?什么类型的申请?预计会多久运行一次?

这些很重要,因为不同的场景需要不同的解决方案:

  1. 如果这是一次性扫描,那么这可能是不必要的优化。即使对于20MB的文本文件,在最坏的情况下也不会超过几分钟。
  2. 如果您有一组输入,并且每个输入都在扫描20MB文件中的所有单词,那么对20MB文件进行排序/索引可能更容易查找匹配并跳过99不必要的比较的百分比。此外,如果输入倾向于重复,那么使用缓存可能是有意义的。
  3. 其他解决方案也可能具有相关性,具体取决于实际问题。

    但是如果你把它归结为只比较两个字符串的前三个字符,我相信这里给出的代码片段和你将得到的一样好 - 它们都是O(1)*,所以有你不能做大幅度的优化。

    *唯一可能不成立的地方是,如果获取字符串的长度是O(n)而不是O(1)(这是C ++中strlen函数的情况),情况并非如此用于Java和C#字符串对象。