fix bug in radix trie

This commit is contained in:
Joeri Exelmans 2025-05-19 17:02:20 +02:00
parent 70fb80a9fc
commit 4fcfea409a
2 changed files with 32 additions and 14 deletions

View file

@ -19,7 +19,7 @@ export const isProperlySorted = trie => {
} }
} }
return true; return true;
} };
// find maximal common prefix, and whether string A is smaller than B // find maximal common prefix, and whether string A is smaller than B
const commonPrefix = (strA, strB) => { const commonPrefix = (strA, strB) => {
@ -34,12 +34,12 @@ const commonPrefix = (strA, strB) => {
} }
} }
return [strA.slice(0, i), false]; return [strA.slice(0, i), false];
} };
// a funny kind of binary search, that assumes 'ls' is a sorted list of strings, and none of the strings have a common prefix // a funny kind of binary search, that assumes 'ls' is a sorted list of strings, and none of the strings have a common prefix
const binarySearch = (ls, key) => { const binarySearch = (ls, key) => {
return __binarySearch(ls, key, 0, ls.length); return __binarySearch(ls, key, 0, ls.length);
} };
const __binarySearch = (ls, key, min, max) => { const __binarySearch = (ls, key, min, max) => {
if (min === max) { if (min === max) {
return [max, ""]; // otherwise we go out of bounds return [max, ""]; // otherwise we go out of bounds
@ -54,7 +54,7 @@ const __binarySearch = (ls, key, min, max) => {
return __binarySearch(ls, key, min, middle); return __binarySearch(ls, key, min, middle);
} }
return __binarySearch(ls, key, middle+1, max); return __binarySearch(ls, key, middle+1, max);
} };
const check = trie => { const check = trie => {
// uncomment if you think shit is broken: // uncomment if you think shit is broken:
@ -62,7 +62,7 @@ const check = trie => {
// throw new Error('not properly sorted!') // throw new Error('not properly sorted!')
// } // }
return trie; return trie;
} };
// insert (key,value) into trie. // insert (key,value) into trie.
export const insert = trie => key => value => { export const insert = trie => key => value => {
@ -118,15 +118,20 @@ export const insert = trie => key => value => {
children: trie.children.with( children: trie.children.with(
insertPos, // position to update insertPos, // position to update
[prefix, { [prefix, {
value: (postFix.length === 0) ? value : undefined,
children: (havePostFix < postFix) children: (havePostFix < postFix)
? [ ? [
[havePostFix, haveChildNode], [havePostFix, haveChildNode],
[postFix, {value, children: []}], [postFix, {value, children: []}],
] ]
: [ : ((postFix.length > 0)
? [
[postFix, {value, children: []}], [postFix, {value, children: []}],
[havePostFix, haveChildNode], [havePostFix, haveChildNode],
], ]
: [
[havePostFix, haveChildNode],
]),
}], }],
), ),
}); });
@ -153,12 +158,12 @@ export const growPrefix = trie => key => {
} }
} }
return ""; return "";
} };
// get array of (key, value) entries whose keys are prefixed by 'key'. // get array of (key, value) entries whose keys are prefixed by 'key'.
export const suggest = trie => key => maxSuggestions => { export const suggest = trie => key => maxSuggestions => {
return __suggest(trie, "", key, maxSuggestions); return __suggest(trie, "", key, maxSuggestions);
} };
export const get = trie => key => { export const get = trie => key => {
if (key === '') { if (key === '') {
@ -171,7 +176,7 @@ export const get = trie => key => {
return get(haveChildNode)(key.slice(haveKey.length)); return get(haveChildNode)(key.slice(haveKey.length));
} }
} }
} };
const __suggest = (trie, path, remaining, maxSuggestions) => { const __suggest = (trie, path, remaining, maxSuggestions) => {
if (maxSuggestions === 0) { if (maxSuggestions === 0) {
@ -205,4 +210,4 @@ const __suggest = (trie, path, remaining, maxSuggestions) => {
} }
return []; return [];
} };

View file

@ -27,6 +27,8 @@ const with7Items = insert(with6Items)('ab')('yup');
console.log(pretty(with7Items)); console.log(pretty(with7Items));
const with8Items = insert(with7Items)('')('hi!'); const with8Items = insert(with7Items)('')('hi!');
console.log(pretty(with8Items)); console.log(pretty(with8Items));
const with9Items = insert(with8Items)('fo')(42);
console.log(pretty(with9Items));
/////////////////// ///////////////////
// Setup TRIE 2 ... // Setup TRIE 2 ...
@ -82,11 +84,22 @@ assert.deepEqual(
]); ]);
assert.equal( assert.equal(
isProperlySorted(with8Items), isProperlySorted(with9Items),
true, true,
"trie should always be properly sorted!" "trie should always be properly sorted!"
); );
assert.equal(
get(with9Items)(''),
"hi!"
)
assert.equal(
get(with9Items)('fo'),
42
)
assert.equal( assert.equal(
isProperlySorted(bigTrie), isProperlySorted(bigTrie),
true, true,