比较两个字符串的大小
# 问题
问题:比较两个字符串的大小,返回较大的字符串。字符串形如12-4-5-6-7-1
,每个数字之间用-
隔开。-
隔开的数字大小也不定,可能超过浏览器或者计算机的精度。
/** a = '12-4-5-6-7-1' b = '1-2-4-5-6-7-2'
* a > b return 1
* a < b return -1
* a == b return 0
*/
1
2
3
4
5
2
3
4
5
# 解题思路
有一种传统的方法是将字符串a
和b
分别转换为数字,然后比较大小。但是这种方法在字符串长度超过浏览器或者计算机的精度时,会出现错误的结果。还可以去除分隔符-
再将每个数字单独作为数组项,遍历数组进行比较。今天不打算用数据解决这个问题,而是用生成器yield
。
生成器yield
可以将一个函数的执行过程分解为多个步骤,每个步骤可以暂停和恢复执行。这样就可以在比较大的字符串时,避免一次性比较所有数字,而是每次比较一个数字,避免精度问题。
# 代码实现
yield
方案实现如下:
var a="1-2-3-4-7-67",b="1-29-3-4-67";
function removeSplitChar(str,splitChar){
return str.split(splitChar).join("")
}
function* numberGenerator(str) {
for (const char of str) {
yield parseInt(char, 10);
}
}
function compareWithGenerators(a, b) {
a=removeSplitChar(a,'-');
b=removeSplitChar(b,'-');
const lengthA=a.length,lengthB=b.length;
if(lengthA > lengthB){
return 1
}else if(lengthA < lengthB){
return -1
}
const genA = numberGenerator(a);
const genB = numberGenerator(b);
while (true) {
const { value: valA, done: doneA } = genA.next();
const { value: valB, done: doneB } = genB.next();
if (doneA && doneB) return 0; // 长度相同且所有段相等
// 比较当前段
if (valA > valB) return 1;
if (valA < valB) return -1;
// 如果相等,继续比较下一段
}
}
console.log(compareWithGenerators(a, b)); // 输出: -1 (a < b)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
编辑 (opens new window)
上次更新: 2025/08/29, 09:40:45