誰ãããœãŒã·ã£ã«ãããã¯ãŒã¯ã®Facebookãç¥ã£ãŠããŸãã å€ãã®äººãããªãã£ã¹ã§ããã°ã©ããèŠã€ããããã«ããã®ãããã¯ãŒã¯ã®ç®¡çè ã«ãã£ãŠå ¬éãããããã°ã©ãã³ã°ã®åé¡ã«ã€ããŠèããããšããããŸã ïŒãã ãããã©ãŒã©ã ã®ã³ã¡ã³ãããå€æãããšããã®æ¹æ³ã¯é·ãéäžæãããŠããŸãïŒã ãããã®åé¡ã解決ããããšãã人ãããŸããã ããã€ãã¯ããã§ããæåããŸããã ããããããã«é¢ãã圌ãã®çµéšãå ±æããã®ã¯å°æ°ã§ããã ãããŠããã®çµéšã¯éåžžã«æçšã§ãã ç§ã®èããéããŠãç§ã¯ãã®çç¥ããããã«ä¿®æ£ããããšã«ããŸããã
å°ããå 責äºé ïŒãã®èšäºã«ã¯ãçŸããã³ãŒããPLOã®ååã®é å®ãåãå ¥ããããŠããèŠåã®é å®ãããã³çŸåšäººæ°ã®ãããã®ä»ã®ãã®ã¯ãããŸããã äœæ¥ã³ãŒããçŸãããªãã¡ã¯ã¿ãªã³ã°ããæéã¯ãã€ã§ããããŸãããèšäºå šäœã§è§£æ±ºããã¿ã¹ã¯ã¯å®éã«åäœããã³ãŒããæžãããšã§ãã
ããã§ã飲é åšã 圌ã¯åŒåžåšã§ãã ããã¯ãfacebookã®åé¡ã«ããã¹ããã¯ã®è€éãã®ã¿ã¹ã¯ã§ãã 圌ãã®åºæºã§ã¯ãããã¯ãŸã£ããè€éã§ã¯ãããŸããã ããã¯ãç§ãããã解決ããã®ã«ããªãã®æ°é±éãè²»ããããšãæ¢ããŸããã§ããïŒéšåçã«ã¯Rubyã§ããã解決ããããšããåºæ¬çãªæ¬²æ±ã®ããïŒã ç§ã¯ãã®ã¿ã¹ã¯ã2çªç®ã«é çªã«å®è¡ãã解決çãèŠã€ããããã«å€å€§ãªåªåãæãããã«ä¿ããäž»ãªã¢ã€ãã¢ã«ç§ãä¿ããã®ã¯åœŒå¥³ã§ããã ãããŠãã¢ã€ãã¢ã¯æ¬¡ã®ãšããã§ãã-ããã°ã©ã ããæ¹æ³ãããããŸãã...
ã¯ã ç§ã¯ITå°éã®ããã»ã©æªããªãæè¡å€§åŠãåæ¥ããDelphiã§æ°å¹ŽéãœãããŠã§ã¢ãç²åŸããŠããŸããã ãã®èããæãã€ããã®ã¯ãªãã§ããïŒ äžç·ã«èŠãŠã¿ãŸãããã
ã¿ã¹ã¯æ¡ä»¶
ã ãããããªãã¯Facebookããã°ã©ããŒã§ãããããèªäœã¯ãã§ã«æªãã¯ãããŸããã ãœãŒã·ã£ã«ãããã¯ãŒã¯ã®ç®¡çè ã¯ãé ã£æã£ã人ã ã«ãã£ãŠæžãããå£ã«æžãããå€æ°ã®ã¡ãã»ãŒãžïŒåœŒãã¯æã åŸæããïŒã«ã€ããŠå¿é ãå§ããŸããã ãœãŒã·ã£ã«ãããã¯ãŒã¯ã®å£ã«éä¿¡ãããã¡ãã»ãŒãžã®æ°ãå€ããããããæåã§ç®¡çããããšã¯ã§ããŸããã ãã ããããã¯åªããããã°ã©ããŒã®åŠšãã«ã¯ãªããŸãããããã»ã¹ãèªååã§ããŸãã
æ¡ä»¶ã¯ç°¡åã§ãã ãœãŒã¹ããã¹ããšçµæã®æžåŒèšå®ãããã³ã³ãŒãã®é©çšå¯Ÿè±¡é åã«é¢ãã詳现ãçç¥ãããšãããã°ã©ã ã«ã¯ãšã©ãŒã®ããããã¹ããšæ£ããåèªã®èŸæžãäžããããŸãã ã¿ã¹ã¯ã¯ãååèªã®ãšã©ãŒæ°ãèšç®ããããã¹ãã®ãšã©ãŒã®åèšéã衚瀺ããããšã§ãã ãšã©ãŒã®æ°ã¯ãèŸæžå ã®åèªã®1ã€ã«å®å šã«æºæ ãããããã«ãåèªã«å¯ŸããŠè¡ãå¿ èŠãããä¿®æ£ã®æ°ã«ãã£ãŠèæ ®ãããŸãã ä¿®æ£ã¯ã1æåã®æ¿å ¥ã1æåã®åé€ã1æåã®çœ®æã§ãã ããŒã...ãããæ°ããæ¹æ³ã¯ããã«ã¯ããããŸãããã倧äžå€«ãç®ãæããæãããã¯ã§ãã è¡ãã ãããããã¿ã¹ã¯ã®é¢ã§ã®éèŠãªè¿œå ã¯ãããã°ã©ã ãæéå ã«æå¹ã§ããå¿ èŠãããããšã瀺ããŸããã
解決çã å埩1
æåã«å¯ŸåŠããåé¡ã¯ãåèªã®ãšã©ãŒã®å®éã®èšç®ã§ãã Googleã§ç°¡åã«æ€çŽ¢ãããšããã¹ãŠã®ãã®ãç§ãã¡ã®åã«ãã§ã«çºæãããŠããããšã瀺ãããç¹å®ã®æ¡ä»¶äžã§ã®åèªã®éãã®å®éçãªææšã¯ãã¬ãŒãã³ã·ã¥ã¿ã€ã³è·é¢ããšåŒã°ããŸãã ãã®è·é¢ã®æ€çŽ¢ã¢ã«ãŽãªãºã ã®èª¬æã¯æ¢ã«Habréã§è¡ãããŠããããã詳现ã«ã€ããŠã¯èª¬æããŸãããRubyã§ã®å®è£ ã玹ä»ããŸãã ãããã£ãŠãç§ãã¡ã®æ±ºå®ã®æ žå¿ã¯æ¬¡ã®ãšããã§ãã
def calc_levenshtein_distance(s,t) n = s.length m = t.length return m if n==0 return n if m==0 d = Array.new(n+1).map!{Array.new(m+1)} for i in 0..n d[i][0]=i end for j in 0..m d[0][j]=j end for i in 1..n for j in 1..m do if s[i-1]==t[j-1] cost=0 else cost=1 end d[i][j] = [d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1] + cost].min end end return d[n][m] end
èŸæžãžã®ãªã³ã¯ã¯åé¡ã®ç¶æ ã§äžããããŸãïŒç§ããããè€è£œããå Žåã«åã㊠ïŒããã¹ãçšã®ãœãŒã¹ããã¹ãã®ããã€ãã®äŸããã©ãŒã©ã ã®åå æ奜家ã«ãã£ãŠæçš¿ãããŸããïŒ 187.in ã david_22719.in ã 4.in ã 12.in ïŒãç¶è¡ã§ããŸãã å°ããå Žåã èŸæžå šäœãèªã¿ãŸãïŒåè¡ã®åèªã§ç°¡åã«ãã©ãŒããããããã¢ã«ãã¡ãããé ã«ãœãŒããããŠããããïŒããœãŒã¹ããã¹ããèªã¿ããµã€ã¯ã«ãéå§ããŸãïŒãœãŒã¹ããã¹ãããã®ååèªã«å¯ŸããŠãèŸæžã§æãè¿ãåèªãæ¢ããŸãã ã©ãã§ããïŒ ã¬ãŒãã³ã·ã¥ã¿ã€ã³è·é¢æ€çŽ¢æ©èœãæ¯ã£ãŠãèŸæžå šäœãå®è¡ããŸãã
def find_word(word, dic) result_word = '' result_cost = 999 dic.each do |dic_word| ld = calc_levenshtein_distance(word, dic_word) if ld<result_cost result_word = dic_word result_cost = ld end end return {:word => result_word, :cost => result_cost} end
ããã°ã©ã ã®æ¬äœããèªã¿åãèŸæžãåŒãããã®ïŒ
total_cost = 0 words.each do |word| total_cost += find_word(word, dic_words)[:cost] end
æåã®ãªãã·ã§ã³ã®å šæã¯ã ããã§ååŸã§ããŸã ã ããã§ã¯ãæåã®ç念ã«ãã§ã«èšªããŠããŸãããã倧äžå€«ãå°æ¥çã«ç§ã®ãæ°ã«å ¥ãã«ãªã£ããæ°ã«å ¥ãã®ãã¹ããã¡ã€ã«ã§ã®æåã®å®è¡ïŒ æåã«187.inãã¡ã€ã«ã®ã»ãšãã©ãã¹ãŠã®å埩ã確èªããŸããïŒ...ããŒãã 10åéåŸ æ©ããåŸããã®ããã°ã©ã ãæéå ã«æå¹ã§ãããšã¯èãã«ããããšãæããã«ãªããŸããã
ãŸããããªãã¯ãã¬ãŒããåããããå Žæãæ¢ãå¿ èŠããããŸãã ãããã£ãŠãããã°ã©ã ã®äž»èŠéšåã¯ãçä¿¡ããã¹ããšèŸæžã«å¿ããŠã2ãµã€ã¯ã«ã§ã©ãããããã¬ãŒãã³ã·ã¥ã¿ã€ã³è·é¢æ€çŽ¢æ©èœã§ãã ãŸããèŸæžã«ã¯18äžè¿ãã®åèªãå«ãŸããŠããŸãã åãçµãã¹ãããšããããŸã...
解決çã å埩2
éå§ããã«ã¯ãæãç°¡åãªæé©åãè¡ããŸãã ãŸããåé¡ã®åèªãå€æŽããã«èŸæžã«ååšããå Žåããã以äžèŠåŽããã«ããã®äžã®ãšã©ãŒã®æ°ããŒãã§ãããšæ³å®ããŸãã
return {:word => word, :cost => 0} if dic.include?(word)
第äºã«ãããã€ãã®äŸã§ã¯éè€ããåèªããããããåé¡ã®ååèªã«å¯ŸããŠæ€çŽ¢çµæãä¿åããŸãã
res = already_found.include?(word) ? already_found[word] : find_word(word, dic_words) already_found[word] ||= res
第äžã«ããããã°åºåãè¿œå ããŸãã ã¿ã¹ã¯ã®æ¡ä»¶ã«ãããããã°ã©ã ã¯ã³ã³ãœãŒã«ã«1ã€ã®æ°åãåºåããå¿ èŠããããŸãããäœæ¥ã®ããã«ããå°ãæ å ±ãèŠããšããã§ãããïŒ2çªç®ã®ãªãã·ã§ã³ã®å šæã¯ãã¡ãã§ã ïŒã ãã®å埩ã«ãããå ¥åãã¡ã€ã«4.inããã³12.inã§ããã°ã©ã ã®æ¯èŒçæ£åžžãªå®è¡æéïŒèªå® ã®ã³ã³ãã¥ãŒã¿ãŒã§çŽ3åïŒãéæããåæ§ã«éèŠãªããšãšããŠãæ£ããçµæãåŸãããšãã§ããŸããã 187.inã®å®è¡ãåŸ æ©ããããšã¯ãåŠçãããŠããååèªã®ã³ã³ãœãŒã«ãžã®åºåã«ãããããããäŸç¶ãšããŠå®¹æã§ã¯ãããŸããã å°ãªããšããããã°ã©ã ãæ£ããæ©èœããŠããããšã確èªã§ããŸãã ãããŸã§ã
解決çã å埩3
ã¿ã¹ã¯ã®æ¡ä»¶ã§ã¯ãåèªã®ãšã©ãŒãä¿®æ£ããæ¹æ³ã¯3ã€ãããªããšæžãããŠããŸãïŒæåãè¿œå ãããæåãåé€ãããæåãä»ã®æåã«çœ®ãæããã ããã¯ãé·ãã1ã ãç°ãªãåèªã¯ãã¬ãŒãã³ã·ã¥ã¿ã€ã³è·é¢ãå°ãªããšã1ã§ãããšããäºå®ãæå³ããŸãã èŸæžã¯åèªã®é·ãã«å¿ããŠã°ã«ãŒãã«åããããšãã§ããŸãã å ¥åããã¹ããã次ã®åèªãåæããããšã«ãããåé¡ã®é·ããšåãåèªã§èŸæžã®æ€çŽ¢ãéå§ãã1ãªã©ã®åèªã§ç¶è¡ã§ããŸãã é·ãã®å·®ãæ€åºãããçŸåšã®æå°è·é¢ãè¶ ãããšããã«ãããã«ç¶è¡ããå¿ èŠããªãããšãããããŸãã
ãŸããå¿ èŠãªæ§é ã®èŸæžãäœæããŸãã
dictionary = {} dic_words.each do |w| dictionary[w.length] ||= [] dictionary[w.length] << w end
次ã«ãèŸæžæ€çŽ¢æ©èœã䜿çšããŠãã¡ã€ã«ãå€æŽããç®çã®é åºã§åèªãå埩åŠçããŸãã
def find_word(word, dic) if dic[word.length] return {:word => word, :cost => 0} if dic[word.length].include?(word) end result_word = '' result_cost = 999 for offset in 0..15 do return {:word => result_word, :cost => result_cost} if result_cost<=offset indexes = [word.length-offset,word.length+offset].uniq indexes.each do |index| next unless dic[index] dictionary_part = dic[index] dictionary_part.each do |dic_word| ld = calc_levenshtein_distance(word, dic_word) if ld<result_cost result_word = dic_word result_cost = ld end end end end return {:word => result_word, :cost => result_cost} end
ãã£ãïŒ 12.inããã³4.inãã¡ã€ã«ã§ã®ããã°ã©ã å®è¡ã¯70ç§ã«ççž®ãããŸããïŒ ããã§å šæãæ¢ããŸã ïŒã ãããŠã 187.inãã¡ã€ã«ã®å®è¡çµæãåŸ ã€ããšãå€æããŸãããçŽ17åã§ãã ç§ã®æ°åŠã®å çãèšã£ãããã«ãããã¯è¯ãã§ãããä»ã®ãšãã2ã€ã§ãã david_22719.inãã¡ã€ã«ã¯ãŸã å°éäžèœã§ãã
解決çã å埩4
Rubyãžã§ã€ã³ããšä»ã®ã€ã³ã¿ãŒããªã¿ãŒèšèªã®æ奜è ãèš±ããŠãã ããããããããã®æ®µéã®ã©ããã§ãå®è¡æãŸã§ã«éèŠãªã¿ã¹ã¯ã§ã¯ãããããããŸããããªãããšã«æ°ä»ã
ãœãªã¥ãŒã·ã§ã³ã飲é æ€ç¥åšã«å®è¡ããåŸïŒ2011幎1æ18æ¥åå10æ40åã«åä¿¡ïŒãæ£ãããšå€æããŸããã ãœãªã¥ãŒã·ã§ã³ã¯ãæé·ã®ãã¹ãã±ãŒã¹ã§1585.775ããªç§å®è¡ãããŸããã
Rubyã®ãœãªã¥ãŒã·ã§ã³ã¯äœåºŠãããŒã¯ãä»ããŠæ»ã£ãŠããŸãã
Facebookã«ããºã«ãœãªã¥ãŒã·ã§ã³ãéä¿¡ããŠããã ãããããšãããããŸãïŒ ãœãªã¥ãŒã·ã§ã³ãbreathalyzerã«å®è¡ããåŸïŒ2011幎1æ18æ¥ãååŸ12æ20åã«åä¿¡ïŒãæ®å¿µãªããããã€ãã®ãã°ãèŠã€ãããããæ£ãããªããšå€æããŸããã
ããã§ã¯ãä»ã®æ¹åæ¹æ³ãæ¢ããšãã§ãã ããã°ã©ã ã®æ žå¿ã¯ãã¬ãŒãã³ã·ã¥ã¿ã€ã³è·é¢ãèšç®ããæ©èœã§ããã¢ã«ãŽãªãºã ã«ã¯è€æ°ã®ã¢ã«ãŽãªãºã ããããŸãããæãåçŽãªãã®ãé€ããŠããããã¯ãã¹ãŠ...èšãæ¹ã¯...ããããèªæã§ã¯ãããŸããã æ°æé調ã¹ãåŸãå¥ã®è§£æ±ºçãæ¢ãããšã«ããŸããã ãããŠèŠã€ããã æ®å¿µãªãããä»ã§ã¯ãªã³ã¯ãèŠã€ããããšãã§ããŸããããã£ãšåã«çãæããããŸããããã¢ã€ãã¢ã¯æ¬¡ã®ãšããã§ãããç¹å®ã®åèªã«ã€ããŠèãããããã¹ãŠã®1次ãšã©ãŒã®ãªã¹ããäœæããèŸæžã«å°ãªããšã1ã€ãããã©ããã確èªããŸãã ã¿ã€ããã¹æ©èœïŒ
def get_possible_edits(word) letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(//) res = [] for i in 0..(word.length-1) str = String.new(word) str[i] = '' res << str end for c in letters for i in 0..(word.length-1) next if word[i]==c str = String.new(word) str[i]=c res << str end end for c in letters for i in 0..(word.length) str = String.new(word).insert(i,c) res << str end end return res end
ãããŠãèŸæžæ€çŽ¢æ©èœã§ã次ã®è¡ãè¿œå ããŸãã
minimum_errors = 1 # , edits = get_possible_edits(word) edits.each do |edit| return {:word => edit, :cost => 1} if dic[edit.length] ? dic[edit.length].include?(edit) : false end minimum_errors = 2 # ,
ããŠããã®åèªã«ã¯å°ãªããšã1ã€ã®ãšã©ãŒãååšãããšããäºå®ãèæ ®ããŠããœãªã¥ãŒã·ã§ã³ã®ãããªãæ€çŽ¢ãçç¥ããŸãïŒ1ã€ã®ãšã©ãŒã§ãã¹ãŠã®ãªãã·ã§ã³ãæ¢ã«æ€èšããããïŒã
for offset in 0..15 do return {:word => result_word, :cost => result_cost} if ((result_cost<=offset) or (result_cost<=minimum_errors)) ... end
ãã®ãããªå€æŽã«ããã 187.inã14åã«ã 12.inã64ç§ã«ã 4.inãäžç¬ã§å®äºããçµæãæ¹åããããšãå¯èœã«ãªããŸããïŒåœç¶ã®ããšã§ãããè€æ°ã®ãšã©ãŒãå«ãåèªã¯ãããŸããïŒã å°ãã®åå©ã ããã«é²ãã§ãåãæ¹æ³ã䜿çšããŠ2次ãŸã§ã®èª€å·®ãèšç®ã§ããŸãã ãã ãã第1ã¬ãã«ã§çºçããå¯èœæ§ã®ãããšã©ãŒã®æ°ã¯åé¡ã®åèªã®é·ããšãšãã«å¹ŸäœåŠçã«å¢å ãã第2ã¬ãã«ã®ãšã©ãŒã®æ°ã¯ç¬¬1ã¬ãã«ã§çºçãããšã©ãŒã®æ°ããäºæ¬¡çã«å¢å ããããšãç解ããŠãã ããã ãããã£ãŠãã³ãŒããè¿œå ããã ãã®å ŽåïŒ
edits.each do |edit| edits2 = get_possible_edits(edit) edits2.each do |edit2| return {:word => edit2, :cost => 2} if dic[edit2.length] ? dic[edit2.length].include?(edit2) : false end end minimum_errors = 3
ããã®åŸãç°¡åã«ãç°åžžã«åä¿¡ãã12.inãã¡ã€ã«ã§ã®ããã°ã©ã ã®å®è¡æéã10åã«å¢ãããŸãã ãã®ã¢ã«ãŽãªãºã ã¯ãçãèšèã§äœ¿çšããããšããå§ãããŸãã ç§ã¯ã6æå以äžã®åèªã§ãããã調ã¹ãããšã§ãæ倧ã®å©ç¹ãåŸãããããšãå®éšçã«ç¢ºç«ããŸããã
if word.length<=6 edits.each do |edit| edits2 = get_possible_edits(edit) edits2.each do |edit2| return {:word => edit2, :cost => 2} if dic[edit2.length] ? dic[edit2.length].include?(edit2) : false end end minimum_errors = 3 end
ãã¡ã€ã«187.inã§ããã®èŠçŽ ã䜿çšãããšãå®è¡æéã®ããã«10ïŒ ãåçã§ããŸãã ãã®æç¹ã§ãäºçŽ°ãªæé©åã¯ãã¹ãŠçµäºããŸããã€ãŸããæ°åŠã«çªå ¥ããæãæ¥ããšããããšã§ãã
解決çã å埩5
ã¬ãŒãã³ã·ã¥ã¿ã€ã³ã®è·é¢ã¯æ°åŠã®æ°ãããã®ã§ã¯ãªãããããèŠã€ããããã«å€ãã®ã¢ã«ãŽãªãºã ãçºæãããŠããŸããããããã®ä»äºãç解ããã«ã¯ãæ°åŠçãªæºåãç¡éã®æéããããŠããªãã®èŠªsã«ãªãªã³ãã¥ã¢ã®ç¥ã ããããšããæºãããªãèªä¿¡ãå¿ èŠã§ãã ç§ã¯äžæ©ä»¥äžãæ°åŠèšç®ãšã¢ã«ãŽãªãºã èšç®ãåæããæçµçã«ãŠãã³ãã³ã¢ã«ãŽãªãºã ã«èœã¡çããŸãã ã
ããã§ãã³ãŒããèšè¿°ããåã«ãæ°åŠã®äœ¿çšã«ã€ããŠå°ãèããå¿ èŠããããŸãã ç¹ã«ããã«èšè¿°ãããŠããã¢ã«ãŽãªãºã ã®æåéãã®å®è£ ãç§ã«ãšã£ãŠã¯ããŸããããªãã£ãã®ã§ãç§ã¯ãã®æ¬è³ªãæ£ããç解ããŠãããã©ããã¯ããããŸããã ããããç§ãç解ããäœãæ©èœãããããäŒãã§ããŸãã
ã¬ãŒãã³ã·ã¥ã¿ã€ã³è·é¢ãèšç®ããããã®ããŒãã«ãæ³åããŠãã ããã ç°¡åã«ããããã«ã瞊æ¹åãã暪æ¹åã«é·ãå Žåãèæ ®ããŸãïŒåèªã®é åºã¯ãã€ã§ãå€æŽã§ãããããäžè¬æ§ã¯å€±ãããŸããïŒã ããŒãã«ã®å³äžã®ã»ã«ã®å€ã«èå³ããããŸãã ã¢ã«ãŽãªãºã ã«ãããšãæåŸã«èšç®ãããŸãã ãã ãããã®å€ãååŸããããã«ããŒãã«å šäœãèšç®ããå¿ èŠã¯ãããŸããïŒ ãŠãã³ãã³æ³ã®æ¬è³ªã¯ãããã€ãã®å¯Ÿè§ç·ãèšç®ãããããšã§ãã èšç®ãã察è§ç·ãšããããæ£ããéžæããæ¹æ³ ãããäž»ãªè³ªåã§ãã
ã¡ã€ã³ã®å¯Ÿè§ç·ããå·Šäžé ããåºãŠãããã®ãšåŒã³ãŸãã æ¯èŒå¯Ÿè±¡ã®åèªã®æåæ°ãåãå Žåãç®çã®å³äžé ã«é 眮ãããŸãã ãã®å¯Ÿè§ç·ã¯ãäœããã£ãŠãåžžã«èšç®ãããŸãã åèšã§ããã€ã®å¯Ÿè§ç·ãå¿ èŠã§ããïŒ æ°åŠçã«æ£åœåããæºåã¯ã§ããŠããŸããããçµéšçã«å°ãªããšã3ã€ã®å¯Ÿè§ç·ãå¿ èŠã§ããããšãããããŸããã
èªé·ã®å·®ãå°ãªããšã2æåã§ããå Žåãã¡ã€ã³ã®å¯Ÿè§ç·ã®å³åŽã®ãã¹ãŠã®å¯Ÿè§ç·ã¯ãå³äžé ã«è§£ã衚瀺ãã察è§ç·ãŸã§åçŽã«èšç®ãããŸãïŒèªé·ãç°ãªããšãé·ãæ¹ãæ°Žå¹³æ¹åã«æžã蟌ãŸãããšæããŸãïŒã
åèªã®é·ãã1æåç°ãªãå Žåã察è§ç·ãã¡ã€ã³ã®å·ŠåŽã«è¿œå ãããåèªã®é·ããåãå Žåã察è§ç·ãã¡ã€ã³ã®å·ŠåŽãšå³åŽã«è¿œå ãããŸãã
å³ã§ã¯ãã¡ã€ã³ã®å¯Ÿè§ç·ã¯ç·è²ã§ãèšç®ããããã®ã¯é»è²ã§ã解ã¯èµ€è²ã§åŒ·èª¿è¡šç€ºãããŠããŸãã
ããŒãã«èšç®é¢æ°ã®åã¹ãããã¯ããã®åšå²ã®3ã€ã®æå°å€ïŒããã³é·ç§»ã³ã¹ãä¿æ°ïŒãšããŠæ°ããã»ã«ã®å€ãèšç®ãããããããŒãã«ã®ã¹ããããããã»ã«ãèšç®ã«åœ±é¿ãäžããªãããã«ãæããã«å€§ããªæ°ïŒããšãã°50ïŒã§åæåããå¿ èŠããããŸãåãšåæ§ã«ãå·Šäžã®ã»ã«ã¯ãŒãã«åæåãããŸãã ã³ãŒãã§ã¯ã次ã®ããã«ãªããŸãã
def min3(a,b,c) m = a < b ? a : b return m < c ? m : c end def calc_levenshtein_distance(s,t) return calc_levenshtein_distance(t,s) if s.length<t.length n = s.length m = t.length return m if n==0 return n if m==0 d = Array.new(m+1).map!{Array.new(n+1).map!{50}} d[0][0]=0 p = (n==m) ? 1 : 0 # q = (nm<=1)? 1 : 0 # for j in 1..[(n-m+p),n].min d[0][j]=d[0][j-1]+1 end for i in 1..m do for j in (i - q)..[(i + n - m + p),n].min do if j==0 d[i][j] = d[i-1][j]+1 else cost = 1 cost = 0 if t[i-1] == s[j-1] d[i][j] = min3(d[i-1][j] + 1 , d[i][j-1] + 1 , d[i-1][j-1] + cost) end end end return d[m][n] end
æ¹åã¯æããã§ãã187.inã¯ãã§ã«6åã§å®äºãã 12.inã¯25ç§ã§å®äºããŠããŸãã ããããããã§ããä»ã®äœããæãã€ãã®ã¯ããããšã§ãã 5åç®ã®å埩ã®å šæã¯ãã¡ãã§ãã
解決çã å埩6
ãã§ã«å éãããŠããæ©èœãå¯èœãªéãå éããã«ã¯ã©ãããã°ããã§ããïŒ ãŸããããšãã°ãããªãã¯åã«ãããåŒã³åºãããšã¯ã§ããŸããã æããã«ä»¥åã«èŠã€ãã£ã以äžã®éã§æããã«äžèŽããªãåèªã®ã¬ãŒãã³ã·ã¥ã¿ã€ã³è·é¢ãèæ ®ããå¿ èŠã¯ãããŸããã ããããé床ãããããåŸãããã«ããã®å€ãèšç®ããã¬ãŒãã³ã·ã¥ã¿ã€ã³è·é¢ãããããã«é«éã«ããæ¹æ³ã¯ïŒ ç§ã¯çæ³ã®ãµããããŸãããããªããšãæãã€ããã®ã§ãã ååèªã«26åã®å€ã®é åãä¿åããããšã«ããŸãããåå€ã¯ããã®åèªã§è±èªã®ã¢ã«ãã¡ãããã®å¯Ÿå¿ããæåãäœåèŠã€ãã£ããã瀺ããŠããŸãã ãããã®é åã䜿çšãã2ã€ã®åèªã®å·®ã¯ãé åã®å¯Ÿå¿ããå€ã®å·®ã®åèšãšããŠèšç®ã§ããŸãã
def arr_diff(a1,a2) res = 0 for i in 0..25 do res += (a1[i]-a2[i]).abs end return res end
ãã¡ããããã®ãããªéãã¯ã¬ãŒãã³ã·ã¥ã¿ã€ã³è·é¢ãããããã«æœè±¡çã§ãããããé«éã«èšç®ã§ããŸãã 圌女ã¯ã©ã®ããã«å©ããããšãã§ããŸããïŒ ã¬ãŒãã³ã·ã¥ã¿ã€ã³è·é¢ã¯ããã®ãããªããã·ã¥ã®éãã«ã©ã®ããã«é¢ä¿ããŸããïŒ æãéèŠãªé¢ä¿ã¯ãåèªã®1æåãè¿œå ããã³åé€ãããšããããã®äž¡æ¹ã®æå³ã«äžåºŠã«1æåãè¿œå ãããããšã§ãã åèªå ã§2ã€ã®æåã亀æãããå Žåãå ã®åèªããã®æ°ããåèªã®ã¬ãŒãã³ã·ã¥ã¿ã€ã³è·é¢ã¯2ã«ãªããŸããã察å¿ããé åã®å·®ã¯ãŒãã«ãªããŸãã æåã®æ§æã¯ä¿æãããŸãã ãããŠãåèªã®æåãä»ã®æåã«å€æŽãããšãé åã®å·®ã¯2å¢å ããŸãããã¬ãŒãã³ã·ã¥ã¿ã€ã³è·é¢ã¯1ã ãã«ãªããŸãããããã£ãŠã äžããã®é åã®å·®ã®å¶éã¯ããªã匱ãã§ãïŒåèªã®é·ãã®å·®ãå·®ãåŒããšãä»»æã®æ°ã®çœ®æãå¯èœã¬ãŒãã³ã·ã¥ã¿ã€ã³è·é¢ã®å¢å ã«ã€ãªããããé åã®å·®ã®å¢å ã«ã¯ãªããªãæåïŒèªã®æå°ãšã©ãŒæ°ãå¥æ°ã®å Žåã課ãããšãã§ããå¯äžã®äžéã¯1ã§ãã ãããã¯æåã®é åã§ã¯éæã§ããŸããïŒãããã³äžèš -é åã®éãã¯ã¬ãŒãã³ã·ã¥ã¿ã€ã³ã®åã®è·é¢ãè¶ ããããšã¯ã§ããŸããã
äžèšã«åºã¥ããŠãã¬ãŒãã³ã·ã¥ã¿ã€ã³è·é¢diffãšãªãã»ããã®é·ãã®éããæã€2ã€ã®åèªã®å Žåãé åã®éãã¯[offsetã2 * diff-offset]ã®ç¯å²ã«ãããšèšããŸãã å®éãããã ãå¶éããããã«ãåèªã®æå°ãšã©ãŒæ°ã®æšå®å€ã䜿çšããããšãã§ããŸãïŒããšãã°ã1次ã®ãã¹ãŠã®ã¿ã€ããã¹ãåæããŠåèªãèŠã€ããããªãã£ãå Žåãå°ãªããšã2ã€ã®ãšã©ãŒããããšèšããŸãïŒã ãšã©ãŒã®æå°æ°ãšã¯ãŒãé·ã®å·®ã®å·®ãå¥æ°ã§ããå ŽåïŒã€ãŸããã¯ãŒãã®é·ãã®å·®ã«å ããŠãå°ãªããšãNåã®ãšã©ãŒãšNã®å¥æ°ãããå ŽåïŒãã¯ãŒãé åã®æå°ã®å¯èœãªå·®ã1å¢ããããšãã§ããŸã- [offset +ïŒmin_errors-offset ïŒïŒ 2ã2 * diff-offset] ïŒå¶æ°Nã®å Žåãé åã®éãã«åœ±é¿ããªãæåã®é åã«ããå¶æ°ã®ã¬ãŒãã³ã·ã¥ã¿ã€ã³ãšã©ãŒãçºçããå¯èœæ§ããããããè¿œå ã®å¶éã課ãããšã¯ã§ããŸããïŒã
ãã®ç¥èã䜿çšããŠãã¬ãŒãã³ã·ã¥ã¿ã€ã³è·é¢èšç®é¢æ°ã«äžããããåèªããã£ã«ã¿ãªã³ã°ããŠã¿ãŸãããã èŸæžã®åèªã®é åã¯ãèŸæžã®èªã¿åãæã«ããã«ã¯ã«ãŠã³ããããŸããããå¿ èŠã«å¿ããŠãçãå ¥åãã¡ã€ã«ã«å¯ŸããŠäžå¿ èŠãªèšç®ãè¡ããªãããã«ãèªã¿åãæã«å¯Ÿå¿ããé åã®ã¿ãåæåããŸãã
dictionary = {} dic_words.each do |w| dictionary[w.length] ||= {} dictionary[w.length][w] = Array.new(26,0) end
çŸåšã®åèªãšèŸæžãæ¯èŒãããã³ã«ãåã®æ¯èŒã®çµæãããããŸãã æ€çŽ¢ããã®è·é¢ã3ã®åèªãæ¢ã«èŠã€ãã£ãŠããå Žåãè·é¢ãé·ãåèªã¯é¢å¿ããªããªãããããã®åèªã«å¯Ÿå¿ããé åã®éãã«å¶éã課ãããšãã§ããŸãã ãã®å Žåã®èŸæžæ€çŽ¢æ©èœã¯æ¬¡ã®ããã«ãªããŸãã
def find_word(word, dic) if dic[word.length] return {:word => word, :cost => 0} if dic[word.length].include?(word) end minimum_errors = 1 # , edits = get_possible_edits(word) edits.each do |edit| return {:word => edit, :cost => 1} if dic[edit.length] ? dic[edit.length].include?(edit) : false end minimum_errors = 2 # , if word.length<=6 edits.each do |edit| edits2 = get_possible_edits(edit) edits2.each do |edit2| return {:word => edit2, :cost => 2} if dic[edit2.length] ? dic[edit2.length].include?(edit2) : false end end minimum_errors = 3 end result_word = '' result_cost = 999 wordhash = Array.new(26,0) word.each_byte{|b| wordhash[b-65]+=1} for offset in 0..15 do return {:word => result_word, :cost => result_cost} if ((result_cost<=offset) or (result_cost<=minimum_errors)) indexes = [word.length-offset,word.length+offset].uniq indexes.each do |index| next unless dic[index] dictionary_part = dic[index] if dictionary_part[dictionary_part.keys.first].max==0 # , dictionary_part.each do |key, val| key.each_byte{|b| val[b-65]+=1} end end lower_bound = (minimum_errors-offset>0 ? minimum_errors-offset : 0).abs%2 + offset higher_bound = 2*result_cost - offset dictionary_part.each do |dic_word, dic_wordhash| a = arr_diff(dic_wordhash,wordhash) next if a<lower_bound or a>higher_bound ld = calc_levenshtein_distance(word, dic_word) if ld<result_cost result_word = dic_word result_cost = ld higher_bound = 2*result_cost - offset end end end end return {:word => result_word, :cost => result_cost} end
ãããã£ãŠã 187.inãã¡ã€ã«ã¯66ç§ïŒ 12.in -5.5ç§ïŒã§å®è¡ã§ããããšãããããŸãã ããã¯ãããã°ã©ã ã®æåã®ããŒãžã§ã³ã§è¡šç€ºãããïŒãŸãã¯è¡šç€ºãããªãïŒæéãšæ¯èŒããŠéåžžã«åªããŠããã david_22719.inãã¡ã€ã«ã®è§£æ±ºçãèŠãã®ã«æ°æéåŸ ã€ããšããã§ããŸããã çµå±ã®ãšãã ãfacebookããããééããã«ã¯ååã§ã¯ãããŸããã
解決çã å埩7
ããããããããç§ã¯éã£ãã å®è¡ãé«éåããæ¹æ³ãç¿åŸããŠããªããããRubyã®äžè¬çãªæ©èœãç¹ã«ããŒãžã§ã³1.8.6ã®æ©èœã«åºã¥ããçŽç²ã«æè¡çãªæ段ã«é Œããªããã°ãªããŸããã§ããã ããšãã°ãäžé æŒç®åïŒaïŒBïŒcïŒã¯åŸæ¥ã®if-elseãããé«éã§ããããšãå®éšçã«ããããŸããã oneãèšç®ã1è¡ã§è¡ããšãäžæå€æ°ãäœæãããªãã·ã§ã³ããäžç¬åãŠãããšãåŠã³ãŸããã çãå€æ°åã¯å®è¡ããã»ã¹ãé«éåã§ãããšããç¥è©±ãåŠå®ããŸããã æ£èŠè¡šçŸã䜿çšããŠãã¡ã€ã«å šäœã解æããããšã¯ãè¡ããšã«èªã¿åããããéãåäœããããšãããããŸãã...ãªããžã§ã¯ãã®äžèŠãªåæåãäžèŠãªã¡ã¢ãªå²ãåœãŠãåé€ããããã«äœæéãã³ãŒãããªãããšãããã«æ°ç§å€±ãããšããããŸããããããã§ãååã§ã¯ãããŸããã§ããããããééããŸãã ãããŠãç§ã¯ãããããŸããã
解決çã çœãæ
ç§ã¯ã圌ããéåžžããã«å ¥ãããšããæå³ã§å®å šã«completelyããªãããšã«æ±ºããŸããã Rubyã§åé¡ã解決ãããšããèããæåŠããŸããã å°ãªããšãçŽç²ãªRubyã§ã¯...ã¯ããããªãã¯æ£ããç解ããã®ã§ãå°ãããŒãããŠCã®åã«é Œãããšã«æ±ºããŸãããæ°æéé©åãªããã¥ã¢ã«ãåžã£ãåŸãç§ã¯2è¡ã®ã¬ãŒãã³ã·ã¥ã¿ã€ã³è·é¢ãèæ ®ããRubyæ¡åŒµãæžããŸããïŒ
#include <ruby.h> #ifndef max #define max( a, b ) ( ((a) > (b)) ? (a) : (b) ) #endif #ifndef min #define min( a, b ) ( ((a) < (b)) ? (a) : (b) ) #endif void Init_levenshtein(); VALUE distance(VALUE self, VALUE rwm, VALUE rwn); void Init_levenshtein() { VALUE cLevenshtein = rb_define_class("Levenshtein",rb_cObject); rb_define_singleton_method(cLevenshtein, "distance", distance, 2); } VALUE distance(VALUE self, VALUE rwm, VALUE rwn) { char *wm, *wn; int res; wm = StringValuePtr(rwm); wn = StringValuePtr(rwn); res = LeveDist(wm,wn); return INT2NUM(res); } int min3(int a, int b, int c) { int Min = a; if (b < Min) Min = b; if (c < Min) Min = c; return Min; } int LeveDist(char *s, char *t) { char* wm; char* wn; int m, n, q, p, cost, i, j; int loop1, loop2; char* d; int res = -1; if (strlen(s) > strlen(t)) { wm = t; wn = s; } else { wm = s; wn = t; } m = strlen(wm); n = strlen(wn); d = calloc((m + 1)*(n + 1),sizeof(char)); memset(d, 50, (m + 1)*(n + 1)); p = (n==m) ? 1 : 0; q = (nm<=1)? 1 : 0; *d = 0; loop1 = min(n, n - m + p); for (j = 1; j <= loop1; j++) *(d + j) = *(d + j - 1) + 1; for (i = 1; i <= m; i++) { loop2 = min(n, i + n - m + p); for (j = (iq); j <= loop2; j++) { if (j == 0) { *(d + i * (n + 1) + j) = *(d + (i - 1)*(n + 1) + j) + 1; } else { cost = 1; if (*(wm + i - 1) == *(wn + j - 1)) cost = 0; *(d + i * (n + 1) + j) = min3(*(d + (i - 1)*(n + 1) + j) + 1, *(d + i * (n + 1) + j - 1) + 1, *(d + (i - 1)*(n + 1) + j - 1) + cost); } } } res = *(d + m * (n + 1) + n); free(d); return res; }
ããŠãããã¯æ¬¡ã®ããã«ãªããŸããïŒ
require 'levenshtein' ... Levenshtein.distance(word,dic_word)
ãã®åŸã6åç®ã®ç¹°ãè¿ãã§èª¬æããèªåèªèº«ã®æé©åãã¡ã€ã³ãã¬ãŒãã«ãªãããã¶ãã¶æåŠããå¿ èŠããããŸããïŒçºæããã®ã«èŠåŽããŠããªãã®æéãããããŸããïŒã
解決çã åå©ïŒ
ç§ã¯èªããªããã°ãªããªããç§ã¯æçµçã«Windowsçšã®çµæã®ãœãªã¥ãŒã·ã§ã³ããã¹ã¿ãŒããŸããã§ãããLinuxã®ä»®æ³ãã·ã³ã§ã³ã³ãã€ã«ãããŠãããã«éä¿¡ãããæ°æéåŸã«ã¡ãŒã«ããã¯ã¹ã«æ¬¡ã®åœ¢åŒã®ã¡ãã»ãŒãžãå±ããŸããã
Facebookã«ããºã«ãœãªã¥ãŒã·ã§ã³ãéä¿¡ããŠããã ãããããšãããããŸãïŒãœãªã¥ãŒã·ã§ã³ã飲é åšã«å®è¡ããåŸïŒ2011幎1æ25æ¥åå3æ4åã«åä¿¡ïŒãæ£ãããšå€æããŸããããœãªã¥ãŒã·ã§ã³ã¯ãæé·ã®ãã¹ãã±ãŒã¹ã§5097.469ããªç§å®è¡ãããŸããã
ãã¡ãããããã¯Cã§ã®å®å šãªæ€çŽ¢ããã3åé ãã§ãããããã§ãååãªéãã§éå§ã§ããŸã
ãããã«
çµè«ãšããŠããã€ãã®ããã«ãããã€ãã®èšèã«ã€ããŠããã®ãããªããã¹ãã®å£ã®åŸãå°ãé埳ãèšãããšã¯çœªã§ã¯ãããŸãããã³ãŒãã®ãã¹ãŠã®èšç®ãã¹ãããããŠçµè«ã«çŽè¡ãã人ãã¡ã«ãšã£ãŠããã®èšäºã¯ãªã³ã©ã€ã³åŒåžåšã®åé¡ã解決ããããšã«ã€ããŠã§ã¯ãããŸããã圌女ã¯Rubyã§ã®ããã°ã©ãã³ã°ã«ã€ããŠã話ããŠããŸãããããã¯ãäžè¬çãªããã°ã©ãã³ã°ãé©åãªãœãªã¥ãŒã·ã§ã³ã®çºèŠã«ã€ããŠã§ããç§ãã¡å šå¡ãåæ§ã®åé¡ã解決ãã矩åãããããã§ã¯ãããŸãããéåžžã«å€ãã®äººã ãæåã«èŠã€ãã解決çãéä¿¡ããŸããããã®æå¹æ§ãããã©ãŒãã³ã¹ãçŸãããå©äŸ¿æ§ãå¿ èŠãšããªããšããçç±ã ãã§æ°ã«ããŸãããæ®å¿µãªããããã®æ¹æ³ã¯è³ãéã³ãããã®ã§ãæã åæ§ã®é»è·ãäžãããšäŸ¿å©ã§ããå¿ã¯ããã°ã©ããŒã®äž»ãªæŠåšã§ãããéšå£«ã®å£ã®ããã«ãç ãæŸãŸããŠæŠéã«åããŠããå¿ èŠããããŸãã
- (Core-i7 2.66 GHz)
- ,
- , , - , Ruby -
- , facebook-
- facebook-
- snack- ( thrift-), ,
- C , 187.in ,