





















@@ -22,6 +22,16 @@ type EdgeActivationNameCandidate = {
2222strongBoundary: boolean;
2323};
242425+type PreparedActivationName = {
26+activationName: string;
27+compact: string;
28+};
29+30+type PreparedEdgeActivationNameCandidate = {
31+candidate: EdgeActivationNameCandidate;
32+compact: string;
33+};
34+2535export function realtimeVoiceActivationNameWordCount(value: string): number {
2636return Array.from(value.matchAll(/[a-z0-9]+/gi)).length;
2737}
@@ -72,25 +82,39 @@ export function matchRealtimeVoiceActivationName(
7282activationNames: string[],
7383maxWords = REALTIME_VOICE_ACTIVATION_NAME_MAX_WORDS,
7484): Extract<RealtimeVoiceActivationNameTranscriptResult, { allowed: true }> | undefined {
85+const preparedActivationNames: PreparedActivationName[] = [];
86+for (const activationName of activationNames) {
87+const normalizedActivationName = normalizeActivationNameCandidate(activationName);
88+if (!normalizedActivationName) {
89+continue;
90+}
91+preparedActivationNames.push({
92+ activationName,
93+compact: compactActivationName(normalizedActivationName),
94+});
95+}
96+if (preparedActivationNames.length === 0) {
97+return undefined;
98+}
99+75100const candidates = [
76101 ...leadingActivationNameCandidates(text, maxWords),
77102 ...trailingActivationNameCandidates(text, maxWords),
78-].toSorted(
79-(left, right) =>
80-compactActivationName(right.heardName).length - compactActivationName(left.heardName).length,
81-);
103+]
104+.map(
105+(candidate): PreparedEdgeActivationNameCandidate => ({
106+ candidate,
107+compact: compactActivationName(candidate.heardName),
108+}),
109+)
110+.toSorted((left, right) => right.compact.length - left.compact.length);
8211183-for (const candidate of candidates) {
84-for (const activationName of activationNames) {
85-const normalizedActivationName = normalizeActivationNameCandidate(activationName);
86-if (!normalizedActivationName) {
87-continue;
88-}
89-const heardCompact = compactActivationName(candidate.heardName);
90-const activationCompact = compactActivationName(normalizedActivationName);
112+for (const { candidate, compact: heardCompact } of candidates) {
113+for (const { activationName, compact: activationCompact } of preparedActivationNames) {
91114const exactMatch = heardCompact === activationCompact;
92115const fuzzyMatch =
93-candidate.edge === "leading" && isFuzzyActivationNameMatch(candidate, activationName);
116+candidate.edge === "leading" &&
117+isFuzzyActivationNameMatch(candidate, heardCompact, activationCompact);
94118if (exactMatch || fuzzyMatch) {
95119return {
96120allowed: true,
@@ -223,9 +247,13 @@ function levenshteinDistance(left: string, right: string): number {
223247return left.length;
224248}
225249226-let previous = Array.from({ length: right.length + 1 }, (_, index) => index);
250+let previous = new Uint32Array(right.length + 1);
251+let current = new Uint32Array(right.length + 1);
252+for (let index = 0; index <= right.length; index += 1) {
253+previous[index] = index;
254+}
227255for (let leftIndex = 0; leftIndex < left.length; leftIndex += 1) {
228-const current = [leftIndex + 1];
256+current[0] = leftIndex + 1;
229257for (let rightIndex = 0; rightIndex < right.length; rightIndex += 1) {
230258const cost = left[leftIndex] === right[rightIndex] ? 0 : 1;
231259current[rightIndex + 1] = Math.min(
@@ -234,9 +262,11 @@ function levenshteinDistance(left: string, right: string): number {
234262previous[rightIndex] + cost,
235263);
236264}
237-previous = current;
265+const nextPrevious = current;
266+current = previous;
267+previous = nextPrevious;
238268}
239-return previous[right.length] ?? Math.max(left.length, right.length);
269+return previous[right.length];
240270}
241271242272function hasOnlyPhoneticSubstitutions(left: string, right: string): boolean {
@@ -274,14 +304,9 @@ function commonPrefixLength(left: string, right: string): number {
274304275305function isFuzzyActivationNameMatch(
276306candidate: EdgeActivationNameCandidate,
277-activationName: string,
307+heardCompact: string,
308+activationCompact: string,
278309): boolean {
279-const normalizedActivationName = normalizeActivationNameCandidate(activationName);
280-if (!normalizedActivationName) {
281-return false;
282-}
283-const heardCompact = compactActivationName(candidate.heardName);
284-const activationCompact = compactActivationName(normalizedActivationName);
285310if (!heardCompact || !activationCompact || activationCompact.length < 5) {
286311return false;
287312}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。