2011-08-23 5 views
14

Ruby에서 아나그램 유형 솔버를 쓰고 싶지만 이렇게 단어 목록에 대해 작동합니다. 단어의Ruby anagram solver

목록은 다음과 같습니다

the 
these 
one 
owner 

내가, 예를 들어 NOE 일부 문자 입력에 사용자를 허용 것이고, 그것은 사용자가 입력 한 문자를 사용하여 만들 수있는 단어에 대한 단어 목록을 검색 할 것이며, one을 다시 가져오고 "eth"또는 "the"를 입력하면 the이 다시 나타납니다. 나는 이것을하기위한 효율적인 방법을 생각하려고 노력해 왔지만 각 단어 주위를 돌아 다니며 단어의 문자와 일치시키고 각 문자의 단어를 확인하고 두 길이가 일치합니다. 누구든지이 일을하는 더 효율적이고 효율적인 방법에 대한 조언을 줄 수 있습니까?

답변

30

큰 아이디어는 분류 할 때 모든 아나그램이 동일한 것입니다. 그래서 만약 당신이 해쉬를 만들었다면 (루비가 이것들을 무엇이라고 부르는 지), 키가 정렬 된 단어이고 그 값은 주어진 키와 정렬되는 단어들의 목록입니다. 그러면, 당신은 매우 빠르게 애널 그램을 찾을 수 있습니다. 단어와 귀하의 해시를 찾고. 나는이 루비 퀴즈 :

class String 

    def permutation(&block) 
    arr = split(//) 
    arr.permutation { |i| yield i.join } 
    end 
end 


wordlist = ["one", "two"] 

"noe".permutation do |i| 
    puts "match found: #{i}" if wordlist.include?(i) 
end 

기본 개념을 해결 저항 할 수 없었다

+1

위대한 아이디어. 다중 단어 분석기는 어때요? 'rrenaud' =>'Ad Rerun'처럼? –

+0

@KimmoLehto는 문장을 배열로 나눈 다음 배열에서 공백 문자의 모든 인스턴스를 제거합니다. 그런 다음 배열을 정렬 한 다음 일치시킵니다. –

2

는 만들고 배열하고 결과를 가지고 올 순열 함수의 사용한다는 것입니다. 그것은 효율적이지 않을지도 모르지만 나는 그것이 우아한 것을 안다. : D라는 이름의 배열을 지정해,

+0

오, 이런, 그냥 사랑해! – thelastinuit

9

rrenaud의 대답은 중대하다, 여기에 루비와 같은 해시를 구성하는 방법의 예는 "words"당신의 사전에있는 단어를 모두 포함하는 :

@words_hash = words.each_with_object(Hash.new []) do |word, hash| 
    hash[word.chars.sort] += [word] 
end 

을 위의 코드는 루비 1.9.2를 가정합니다. 이전 버전을 사용하는 경우 chars은 존재하지 않지만 .split('').sort을 사용할 수 있습니다.

해시의 기본 개체가 빈 배열로 설정되어 있기 때문에 해시를 걱정할 필요가 없기 때문에 코딩을 쉽게하는 경우가 있습니다.

자료 : https://github.com/DavidEGrayson/anagram/blob/master/david.rb

+3

이것은'words.group_by {| word |와 동일합니다. word.chars.sort}' –

+0

멋지지만 실제로는 이렇게해야합니다 :'@words_hash = words.group_by {| word | word.chars.sort}; @ words_hash.default = []' –

4

하나의 해결책이 될 수 :

def combine_anagrams(words) 
    output_array = Array.new(0) 
    words.each do |w1| 
    temp_array = [] 
    words.each do |w2| 
     if (w2.downcase.split(//).sort == w1.downcase.split(//).sort) 
     temp_array.push(w2) 
     end 
    end 
    output_array.push(temp_array) 
    end 
    return output_array.uniq 
end 
0
def combine_anagrams(words) 
    cp = 0 
    hash = Hash.new [] 
    words.each do |word| 
    cp += 1 
    (cp..words.count).each do |i| 
     hash[word.to_s.chars.sort.join] += [word] 
    end 
    hash[word.to_s.chars.sort.join] = hash[word.to_s.chars.sort.join].uniq 
    end 
    return hash 
end 
0

여기 내 매우 유사합니다. 사전 파일에서 읽고 정렬 된 문자를 배열로 비교합니다. 정렬은 미리 선택된 후보자에 대해 이루어집니다.

def anagrams(n) 
    text = File.open('dict.txt').read 

    candidates = [] 
    text.each_line do |line| 
    if (line.length - 1) == n.length 
     candidates << line.gsub("\n",'') 
    end 
    end 

    result = [] 

    candidates.each do |word| 
    if word.chars.sort == n.chars.sort 
     result << word 
    end 
    end 

    result 

end 
관련 문제