Anagram

Hej,
Szukam rozwiązania.

mam coś takiego:

list = File.read('dictionary.txt').split('\n') list => ["stop\tops\post\test\estg\tylo"]
jak wyszukać w tym ciągu znaków tylko anagramy słowa ostp czyli stop, post i tops ??

String przeszukujesz wyrażeniem regularnym używając na nim metody .match http://ruby-doc.org/core-1.9.2/String.html#method-i-match

Alternatywa (np. działająca w sytuacji, gdy litery mogą się powtarzać, a faktycznie poszukujesz anagramów): posortuj litery w źródle, posortuj litery w każdym z potencjalnych wyników, porównaj posortowane.

okej, a jak najlepiej pociąć ten string stop\tops\post\test\estg\tylo ,żeby można było sortować wyniki?

a = “stop\tops\post\test\estg\tylo”

b = a.split("")

b.sort

Tak krok po kroku ;]

[quote=regedarek]Hej,
Szukam rozwiązania.

mam coś takiego:

list = File.read('dictionary.txt').split('\n') list => ["stop\tops\post\test\estg\tylo"]
jak wyszukać w tym ciągu znaków tylko anagramy słowa ostp czyli stop, post i tops ??[/quote]

[code=ruby]def anagrams(word, list)

Ruby 1.9 ma Array#permutation

word.split(’’).permutation.map { |x| x.join(’’) } & list
end

list = File.read(‘dict.txt’).split("\n")
p anagrams(“stop”, list)[/code]

Dzięki hosiawak - czy wiesz może, gdzie w dokumentacji znaleźć coś o

word.split('').permutation.map { |x| x.join('') } & list

??

Gdyż nie wiedziałem, gdzie znaleźć informacje na ten temat.

[quote=regedarek]czy wiesz może, gdzie w dokumentacji znaleźć coś o

word.split('').permutation.map { |x| x.join('') } & list

[/quote]
tzn.?
String#split
Array#permutation
Array#map
Array#join
Array#&

Dzielisz string na pojedyńcze znaki, potem robisz permutację tych znaków, każdą permutację join-ujesz do stringa i wybierasz te, które powtarzają się w list :slight_smile:

[code=ruby]word = ‘kot’

word.split(’’) #=> [“k”, “o”, “t”]

Tu oczywiście .to_a nie jest potrzebne. Dałem to żeby wyświetlić tablicę a nie enumerator (#<Enumerator: [“k”, “o”, “t”]:permutation>). Normalnie .map można wykonywać na Enumeratorze

word.split(’’).permutation.to_a #=> [[“k”, “o”, “t”], [“k”, “t”, “o”], [“o”, “k”, “t”], [“o”, “t”, “k”], [“t”, “k”, “o”], [“t”, “o”, “k”]]

word.split(’’).permutation.map {|p| p.join(’’)} #=> [“kot”, “kto”, “okt”, “otk”, “tko”, “tok”][/code]

<% @ost_dict = AttDict.find(:last) %> <%= p @ost_dict.link %> <% list = File.read(@ost_dict.link).split("\n") %> <% p anagrams("stop", list) %>
jak wstawić do File.read @ost_dict.link ?

dostaje błąd, że to nie string

A co zwraca metoda link? Skoro dostajesz błąd, że to nie String, to znaczy że nie zwraca stringa :wink:
Dodaj to_s w metodzie link, ewentualnie w tym kodzie który podałeś jeżeli nie chcesz żeby link zawsze zwracało Stringa.

 <%= p @ost_dict.link %>

=> to zwraca /uploads/att_dict/link/2/dictionary.txt

Katalog /uploads/ jest gdzie? W katalogu public?

Spróbuj może:

File.open(Rails.root.join('public' + @ost_dict.link))

dzięki działa
Dałem:

<% list = File.read("public" + @ost_dict.link.to_s).split("\n") %>

Pozdrawiam

[quote=hosiawak][code]# Ruby 1.9 ma Array#permutation
word.split(’’).permutation.map { |x| x.join(’’) } & list
end

list = File.read(‘dict.txt’).split("\n")
p anagrams(“stop”, list)[/code]
[/quote]
Dla długich wyrazów to rozwiązanie jest strasznie wolne (Polecam sprawdzić ile czasu będzie sprawdzał parę anagramów KONWERSATORIUM - KONSERWATORIUM).
Proponuje w zamian coś takiego:

def anagrams(word,list) signature = word.split("").sort.join list.select { |w| w.split("").sort.join == signature} end