This is a codewars above level 3 question.
Original question:
Description:
I ' m sure, you know Google's "Did you mean ...?" When you entered a search term and mistyped a word. In this kata we want to implement something similar.
You'll get a entered term (lowercase string) and an array of known words (also lowercase strings). Your task is to find out, which word from the dictionary are most similar to the entered one. The similarity is described by the minimum number of letters you has to add, remove or replace with order to get from the E Ntered Word to one of the dictionary. The lower the number of required changes, the higher the similarity between each of the words.
Same words is obviously the most similar ones. A word that needs one letter to being changed is more similar to another word this needs 2 (or more) letters to be changed. e.g. the mistyped term was more similar to (1 letter to being berr
beer
replaced) than to barrel
(3 letters to being changed in Total).
Extend the dictionary in a-out, that's it's able to return your the most similar word from the list of known words.
Code Examples:
Dictionary fruits =NewDictionary (Newstring[]{"Cherry", "pineapple", "melon", "strawberry", "raspberry"}); Fruits.findmostsimilar ("Strawbery");//must return "Strawberry"Fruits.findmostsimilar ("Berry");//must return "Cherry"Dictionary Things=NewDictionary (NewString[]{"Stars", "Mars", "Wars", "codec", "Codewars"}); Things.findmostsimilar ("Coddwars");//must return "Codewars"Dictionary Languages=NewDictionary (Newstring[]{"JavaScript", "Java", "Ruby", "PHP", "Python", "Coffeescript"}); Languages.findmostsimilar ("Heaven");//must return "Java"Languages.findmostsimilar ("JavaScript");//must return "JavaScript" (same words is obviously the most similar ones)
I know, many of you would disagree that Java are more similar to heaven than all the other ones, but in this kata it is;)
Additional notes:
- There is always exactly one possible solution
The general meaning of this question is, give you a string array ss, and a string s, from the string array ss to find the minimum number of operations can become the string s of the string.
What is the minimum number of operations ? is two strings, each add or delete or replace a single character, the operand plus 1, the smallest operand of two string is the most similar string
Do not understand the original question (in fact, English is not so difficult, the use of Youdao notes to understand the meaning of the question is not too difficult)
I didn't think of any good solution to this problem, but I had to use stupid methods to solve the problem.
(1) I compare each string in the given array to the target string, calculate their operands separately, and then take the string with the smallest number of operands . (General idea)
(2) The method of calculating the operand, if there is a string a and string B:
Step 1. Take each character of a, then create a new 3 string, respectively, add a character corresponding to B, delete the current character, and replace the character that corresponds to the position of the current character B.
Then all the generated strings are compared to the target string one at a time, and the most similar one is taken out, and this is the operand plus 1.
Step 2. If the string generated in the previous step is equal to the target string, the end runs. Otherwise, take the most similar string generated in the previous step and proceed to step one until the end
Record the number of times per loop, and finally the total number of operands
(3) How to count the most similar strings?
Compare the characters in the corresponding positions of two strings for equality, equal to 1, unequal to 1, and the higher the last number, the greater the similarity.
Like ' abc ' and ' ABCD ', similar values are 3. ' BBC ' and ' ABCD ', similar values are 2. ' abc ' and ' Qabc ', the similarity value is 0, because the corresponding position is not equal
I am very dissatisfied with the way I do this problem, but I did not think of a better method, this method is very inefficient, the time complexity is probably O (n^4).
This is definitely the most time-complicated code I've ever written, and there are a lot of people on codewars that are better than my way of solving the problem.
But because there is no explanation, I looked at the discovery did not understand how to read. There is no time, wait for time to be sure to redo the problem again
The following is the code, because I was using JS to do this problem, so is the JS code. Should not have a big impact on it, the Java should be JS
functionDictionary (words) { This. Words =words;}
The string in the array, followed by the target string comparison, computes the desired operand, returns the string with the smallest operand Dictionary.prototype.findMostSimilar=function(term) {varCount = 99999; varresult = ""; for(vari = 0;i< This. words.length;i++) { varNextcount = This. Gettotal ( This. Words[i],term); if(Nextcount <count) {Count=Nextcount; Result= This. Words[i]; } } returnresult;}
Compare two string gaps, same position with same characters plus 1, minus 1
the greater the last value, the more similar the two strings Dictionary.prototype.count=function(STR1,STR2) {varCountnum = 0, result = 0; while(Countnum<str1.length | | countnum<str2.length) {if(Str1.charat (countnum) = =Str2.charat (Countnum)) {Result++; }Else{result--; } countnum++; } returnresult;} each character in the str1 string is deleted, replaced, added, and all strings are placed in the array, and the similar values of each string and target string are computed in turn
Takes the most similar string as the base string for the next calculation
//Here's a bit of a mess, as I've enumerated all the possibilities that the current string can do, and then find the string that most closely resembles the target string in these possible strings, and then in the next enumeration Dictionary.prototype.getNext=function(STR1,STR2) {varCountnum = 0, result = "", arr = [];
//Remove each character in turn while(Countnum<str1.length | | countnum<str2.length) {varCHAR_STR1 =Str1.charat (Countnum); varCHAR_STR2 =Str2.charat (Countnum); varARR_STR1 = Str1.split (""); varARR_STR2 = Str2.split (""); //add a character to the current character position in a str2 varClone = Arr_str1.slice (0); Clone.splice (Countnum,0, CHAR_STR2); Arr.push (Clone.join ("")); //subtract the current character varClone = Arr_str1.slice (0); Clone.splice (Countnum,1); Arr.push (Clone.join (""));
//If the current position character is not equal to the current position character of the target string, the target character is replaced if(Char_str1! =char_str2) {//Change varClone = Arr_str1.slice (0); Clone.splice (Countnum,1, CHAR_STR2); Arr.push (Clone.join ("")); } countnum++; } countnum=-10000;
calculates a similar value for all generated strings, whichever is the maximum, as the next reference string for(vari=0;i<arr.length;i++) {varCount = This. Count (ARR[I],STR2); if(Count >countnum) {Countnum=count; Result=Arr[i]; } } returnResult;}
//The total number of operations required to get str1 into str2 Dictionary.prototype.getTotal=function(STR1,STR2) {if(str1 = =str2) {return0; } varTotal = 0;
If STR1 has not yet become str2, proceed to the next operation
Total record number of operations
while(STR1! =str2) {str1= This. GetNext (STR1,STR2); Total++; } returnTotal ;}
Find the most similar string