在 JavaScript 中比较字符串的最佳方法?[复制]

Optimum way to compare strings in JavaScript? [duplicate]

提问人:HRJ 提问时间:1/30/2010 最后编辑:sg7HRJ 更新时间:11/10/2023 访问量:985680

问:

这个问题在这里已经有答案了:
10年前关闭。

社区在 10 个月前审查了是否重新讨论这个问题,并将其关闭:

原始关闭原因未解决

我正在尝试优化一个函数,该函数在 JavaScript 中对字符串进行二进制搜索。

二进制搜索要求您知道键是枢轴还是枢轴。==<

但这需要在 JavaScript 中进行两个字符串比较,这与同类语言不同,后者具有返回三个值(小于、等于、大于)的函数。Cstrcmp()(-1, 0, +1)

JavaScript 中是否有这样的原生函数,可以返回一个三元值,以便在二进制搜索的每次迭代中只需要一个比较?

JavaScript 字符串 优化 比较 binary-search

评论

13赞 1'' 7/21/2013
return str1 < str2 ? -1 : str1 > str2;?
6赞 HRJ 7/21/2013
@1“这不是最佳选择;需要两个字符串比较。
4赞 1'' 7/22/2013
它仍然比我的机器快一个数量级(!)。@Gumbo的自定义可能会更快,具体取决于字符串的相等比较的内部实现的优化程度。localeCompare()strcmp()
4赞 Pizzaiola Gorgonzola 5/4/2014
无论如何,你需要两个比较!,一个查看 A > B 另一个查看它们是否相等,javascript 可以非常快速地确定字符串是否相等,因为,如果它们相等,它们就是同一个对象,这就像比较两个指针一样,字符串是“原子化”的,存储在哈希表中,所以每个字母组合, 只有一个实例存在。
2赞 Dan Nissenbaum 11/26/2015
我建议重新打开这个问题,而不是提到一个问题,即使该问题的答案是相同的,因为我认为并非所有寻找这个问题答案的人都会知道。strcmpstrcmp

答:

688赞 Daniel Vassallo 1/30/2010 #1

您可以使用 localeCompare() 方法。

string_a.localeCompare(string_b);

/* Expected Returns:

 0:  exact match

-1:  string_a < string_b
 
 1:  string_a > string_b

 */

延伸阅读:

评论

14赞 kennebec 1/31/2010
不幸的是,stringCompare 并不可靠。Opera、IE、Firefox、Chrome 和 Safari 都为 'dog'.localeCompare('cat') 返回 1,这是意料之中的,当你反转调用方和参数时,返回 -1。BUt 大写字母行为异常 - 'dog'.localeCompare('Dog') 在我测试的浏览器中,只有 Safar 4 返回 1。它在 IE8 和 firefox 3 中返回 -1,而 Opera 9 和 Chrome 都返回 +32。
33赞 Fabrice 3/3/2011
如果需要不区分大小写的比较,可以使用 toLowerCase 或 toLocaleLowerCase。
2赞 JoshVarty 3/21/2012
我认为重要的是要注意 V8 (Chrome) 似乎对 ECMA-262 的解释与 localeCompare 上的 IE/Firefox 不同。例如:“a”.localeCompare(“Z”) 应该返回 -1,但返回 7,这是 “a” 的字符代码 - “Z” 的字符代码。不幸的是,规范中的语言是松散的,指定 localeCompare() 返回负数、正数或 0。(不是特别的 -1、1、0)。我提交了一份错误报告,希望这可能会改变,但自 2010 年 8 月以来,这一直是一个问题,所以我怀疑它是否会改变。
10赞 Gerben Jacobs 7/12/2013
显然,您最好自己比较一下;jsperf.com/localecompare
2赞 HRJ 7/22/2013
@GerbenJacobs 谢谢你。我还从中推导出了一个更大的基准(二进制搜索):jsperf.com/localecompare/2
15赞 Gumbo 1/30/2010 #2

您可以使用比较运算符来比较字符串。函数可以这样定义:strcmp

function strcmp(a, b) {
    if (a.toString() < b.toString()) return -1;
    if (a.toString() > b.toString()) return 1;
    return 0;
}

编辑下面是一个字符串比较函数,它最多需要 min { length(a), length(b) } 比较来判断两个字符串之间的关系:

function strcmp(a, b) {
    a = a.toString(), b = b.toString();
    for (var i=0,n=Math.max(a.length, b.length); i<n && a.charAt(i) === b.charAt(i); ++i);
    if (i === n) return 0;
    return a.charAt(i) > b.charAt(i) ? -1 : 1;
}

评论

12赞 Pointy 1/31/2010
但是这个例程完全是 OP 不想做的事情:有两个字符串比较(更不用说那些对“toString”的函数调用了)。
1赞 Gumbo 1/31/2010
@Pointy:仅靠一个比较是不可能的。您至少需要 min {, } 步长(一次比较两个字符)来确定字符串是否相等。a.lengthb.lengthlocaleCompare
2赞 Pointy 1/31/2010
不,localeCompare 不会在内部执行此操作。比较字符是作为减法实现的,因此一旦该操作的非零结果,您就知道答案。您的答案可以重新比较每个字符串的所有字符。
0赞 Gumbo 1/31/2010
@Pointy:但是减法是逐个字符完成的。这就是重点。这最多需要(至少不是我写的)min {, } 步(在两个字符串相等的情况下)。但你是对的。最好先测试平等性,因为这需要最多的步骤。a.lengthb.length
0赞 HRJ 1/31/2010
@Gumbo localeCompare 不一定是 Javascript 的,对吧?它可以在本地实现。或者我错过了什么......
82赞 Cipi 1/30/2010 #3

好吧,在 JavaScript 中,您可以检查两个字符串中与整数相同的值,因此您可以这样做:

  • "A" < "B"
  • "A" == "B"
  • "A" > "B"

因此,您可以创建自己的函数来检查字符串,其方式与 .strcmp()

因此,这将是执行相同操作的函数:

function strcmp(a, b)
{   
    return (a<b?-1:(a>b?1:0));  
}

评论

16赞 Pointy 1/31/2010
再次阅读原始问题!!关键是要避免进行多个字符串比较。
19赞 Cipi 1/31/2010
哦对不起。没看到...至少这对某人有用。=|