字典序算法详解

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
var strCode = function(s){
let tokens = s.split('')
if(tokens.length === 1){
return ('z'.charCodeAt(0) - tokens[0].charCodeAt(0)) * (10 ** 0)
}
let result = 0
for(let i = tokens.length - 1, j = 1; i > 0 ; i--,j++){
result += ('z'.charCodeAt(0) - tokens[i].charCodeAt(0)) * (10 ** j)
}
return result;
}
function compareStrings_(s1, s2) {
let tokens1 = s1.split('')
let tokens2 = s2.split('')
for(let i = 0; i < tokens1.length; i++){
tokens1[i] = tokens1[i].charCodeAt(0)
}
for(let i = 0; i < tokens2.length; i++){
tokens2[i] = tokens2[i].charCodeAt(0)
}
let result = 0;
let minLen = -1;
if(tokens1.length < tokens2.length){
minLen = tokens1.length;
result = -1
}else if(tokens1.length > tokens2.length){
minLen = tokens2.length;
result = 1;
}else {
minLen = tokens1.length;
result = 0;
}
//console.log(tokens1,tokens2,minLen,result)
//双指针比较
let pointer1 = 0
let pointer2 = 0
if(tokens1[0] > tokens2[0]){
return 1
}else if(tokens1[0] === tokens2[0]){

}else{
return -1;
}
while(tokens1[pointer1] === tokens2[pointer2]){
pointer1++;
pointer2++;
if(tokens1[pointer1] > tokens2[pointer2]){
result = 1
break;
}
if(tokens1[pointer1] < tokens2[pointer2]){
result = -1
break;
}
if(pointer1 === minLen || pointer2 === minLen){
break
}
}
return result;
}
function compareStrings(s1, s2) {
return s1.localeCompare(s2);
}

function randomString(length) {
const chars = 'abcdefghijklmnopqrstuvwxyz';
let result = '';
for (let i = 0; i < length; i++) {
result += chars[Math.floor(Math.random() * chars.length)];
}
return result;
}

function testCompareFunctions(iterations = 1000, maxStrLen = 10) {
const progressBarLength = 50; // 进度条长度
for (let i = 0; i < iterations; i++) {
const len1 = Math.floor(Math.random() * maxStrLen) + 1; // 随机生成字符串长度
const len2 = Math.floor(Math.random() * maxStrLen) + 1;
const s1 = randomString(len1); // 随机生成第一个字符串
const s2 = randomString(len2); // 随机生成第二个字符串

const result1 = compareStrings_(s1, s2); // 用自定义的 compareStrings_ 函数
const result2 = compareStrings(s1, s2); // 用内置的 localeCompare 函数

// 将 localeCompare 的结果标准化为 -1, 0, 1 以进行比较
const normalizedResult2 = result2 === 0 ? 0 : (result2 > 0 ? 1 : -1);

if (result1 !== normalizedResult2) {
console.log(`Test failed for inputs: "${s1}" and "${s2}"`);
console.log(`compareStrings_ result: ${result1}`);
console.log(`localeCompare result: ${normalizedResult2}`);
return; // 一旦发现不一致,停止测试并打印错误信息
}

// 进度条每隔一定的迭代次数更新
if (i % Math.floor(iterations / 100) === 0 || i === iterations - 1) {
const progress = (i / iterations) * 100; // 计算百分比
const progressChars = Math.floor((progress / 100) * progressBarLength); // 进度条符号的数量
const progressBar = '='.repeat(progressChars) + ' '.repeat(progressBarLength - progressChars); // 构建进度条
process.stdout.write(`\r[${progressBar}] ${progress.toFixed(2)}%`); // \r 使光标回到行首,覆盖之前的输出
}
}
console.log('\nAll tests passed!');
}

function testPerformance(iterations = 1000000, maxStrLen = 10) {
const strings = [];

// 预生成随机字符串对
for (let i = 0; i < iterations; i++) {
const len1 = Math.floor(Math.random() * maxStrLen) + 1;
const len2 = Math.floor(Math.random() * maxStrLen) + 1;
const s1 = randomString(len1);
const s2 = randomString(len2);
strings.push([s1, s2]);
}

// 测试自定义 compareStrings_ 的性能
console.time('Custom compareStrings_');
for (let i = 0; i < iterations; i++) {
compareStrings_(strings[i][0], strings[i][1]);
}
console.timeEnd('Custom compareStrings_');

// 测试内置 localeCompare 的性能
console.time('Built-in localeCompare');
for (let i = 0; i < iterations; i++) {
strings[i][0].localeCompare(strings[i][1]);
}
console.timeEnd('Built-in localeCompare');
}

// 运行测试
testCompareFunctions(1000); // 这里设置较小的迭代次数,方便观察进度
// 运行性能测试
testPerformance(1000); // 设置 1000 次测试
//[================================================= ] 99.90%
//All tests passed!
//Custom compareStrings_: 0.395ms
//Built-in localeCompare: 0.158ms