@@ -49,17 +49,17 @@ private IEnumerable<string> GetPossibleTokens(Command targetSymbol, string token
4949 . Select ( symbol =>
5050 symbol . Aliases
5151 . Union ( symbol . Aliases )
52- . OrderBy ( x => GetDistance ( token , x ) )
53- . ThenByDescending ( x => GetStartsWithDistance ( token , x ) )
52+ . OrderBy ( x => TokenDistances . GetLevensteinDistance ( token , x ) )
53+ . ThenByDescending ( x => TokenDistances . GetStartsWithDistance ( token , x ) )
5454 . First ( )
5555 ) ;
5656
5757 int ? bestDistance = null ;
5858 return possibleMatches
59- . Select ( possibleMatch => ( possibleMatch , distance : GetDistance ( token , possibleMatch ) ) )
59+ . Select ( possibleMatch => ( possibleMatch , distance : TokenDistances . GetLevensteinDistance ( token , possibleMatch ) ) )
6060 . Where ( tuple => tuple . distance <= _maxLevenshteinDistance )
6161 . OrderBy ( tuple => tuple . distance )
62- . ThenByDescending ( tuple => GetStartsWithDistance ( token , tuple . possibleMatch ) )
62+ . ThenByDescending ( tuple => TokenDistances . GetStartsWithDistance ( token , tuple . possibleMatch ) )
6363 . TakeWhile ( tuple =>
6464 {
6565 var ( _, distance ) = tuple ;
@@ -71,82 +71,5 @@ private IEnumerable<string> GetPossibleTokens(Command targetSymbol, string token
7171 } )
7272 . Select ( tuple => tuple . possibleMatch ) ;
7373 }
74-
75- private static int GetStartsWithDistance ( string first , string second )
76- {
77- int i ;
78- for ( i = 0 ; i < first . Length && i < second . Length && first [ i ] == second [ i ] ; i ++ )
79- { }
80- return i ;
81- }
82-
83- //Based on https://blogs.msdn.microsoft.com/toub/2006/05/05/generic-levenshtein-edit-distance-with-c/
84- private static int GetDistance ( string first , string second )
85- {
86- // Validate parameters
87- if ( first is null )
88- {
89- throw new ArgumentNullException ( nameof ( first ) ) ;
90- }
91-
92- if ( second is null )
93- {
94- throw new ArgumentNullException ( nameof ( second ) ) ;
95- }
96-
97-
98- // Get the length of both. If either is 0, return
99- // the length of the other, since that number of insertions
100- // would be required.
101-
102- int n = first . Length , m = second . Length ;
103- if ( n == 0 ) return m ;
104- if ( m == 0 ) return n ;
105-
106-
107- // Rather than maintain an entire matrix (which would require O(n*m) space),
108- // just store the current row and the next row, each of which has a length m+1,
109- // so just O(m) space. Initialize the current row.
110-
111- int curRow = 0 , nextRow = 1 ;
112- int [ ] [ ] rows = { new int [ m + 1 ] , new int [ m + 1 ] } ;
113-
114- for ( int j = 0 ; j <= m ; ++ j )
115- {
116- rows [ curRow ] [ j ] = j ;
117- }
118-
119- // For each virtual row (since we only have physical storage for two)
120- for ( int i = 1 ; i <= n ; ++ i )
121- {
122- // Fill in the values in the row
123- rows [ nextRow ] [ 0 ] = i ;
124- for ( int j = 1 ; j <= m ; ++ j )
125- {
126- int dist1 = rows [ curRow ] [ j ] + 1 ;
127- int dist2 = rows [ nextRow ] [ j - 1 ] + 1 ;
128- int dist3 = rows [ curRow ] [ j - 1 ] + ( first [ i - 1 ] . Equals ( second [ j - 1 ] ) ? 0 : 1 ) ;
129-
130- rows [ nextRow ] [ j ] = Math . Min ( dist1 , Math . Min ( dist2 , dist3 ) ) ;
131- }
132-
133-
134- // Swap the current and next rows
135- if ( curRow == 0 )
136- {
137- curRow = 1 ;
138- nextRow = 0 ;
139- }
140- else
141- {
142- curRow = 0 ;
143- nextRow = 1 ;
144- }
145- }
146-
147- // Return the computed edit distance
148- return rows [ curRow ] [ m ] ;
149-
150- }
15174 }
15275}
0 commit comments