2013-02-20 35 views
5

Trong ruby ​​1.9.3, tôi đang cố gắng viết một chương trình sẽ tìm tất cả các từ có số n được lấy từ một tập hợp tùy ý nhân vật. Ví dụ: nếu tôi được tặng các ký tự [b, a, h, s, v, i, e, y, k, s, a] và n = 5, tôi cần tìm tất cả các từ có 5 chữ cái có thể chỉ được thực hiện bằng cách sử dụng những ký tự đó. Sử dụng danh sách từ 2of4brif.txt từ http://wordlist.sourceforge.net/ (để bao gồm các từ Anh và cách đánh vần, quá), tôi đã cố gắng đoạn mã sau:Tìm và in các dòng trong một tệp chính xác khớp chuỗi hoặc regexp (Ruby)

a = %w[b a h s v i e y k s a] 
a.permutation(5).map(&:join).each do |x| 
    File.open('2of4brif.txt').each_line do |line| 
    puts line if line.match(/^[#{x}]+$/) 
    end 
end 

này không có gì (không có thông báo lỗi, không có đầu ra, như thể đông lạnh). Tôi cũng đã cố gắng biến thể dựa trên các chủ đề sau:

What's the best way to search for a string in a file?

Ruby find string in file and print result

How to search for exact matching string in a text file using Ruby?

Finding lines in a text file matching a regular expression

Match a content with regexp in a file?

How to open a file and search for a word?

Mọi biến thể tôi đã thử đều dẫn đến:

1) Làm lạnh;

2) In tất cả các từ trong danh sách có chứa các hoán vị 5 ký tự (tôi cho rằng đó là những gì nó đang làm; tôi đã không đi qua và kiểm tra tất cả hàng nghìn từ đã in); hoặc

3) In tất cả các hoán vị 5 ký tự được tìm thấy trong các từ trong danh sách (một lần nữa, tôi cho rằng đó là những gì nó đang làm).

Một lần nữa, tôi không tìm kiếm các từ chứa hoán vị 5 ký tự, tôi đang tìm các hoán vị 5 ký tự là từ hoàn chỉnh và chính chúng, do đó, một dòng trong tệp văn bản được in nếu nó là một kết hợp hoàn hảo với một hoán vị.

Tôi đang làm gì sai? Cảm ơn trước!

+0

Và đó là một câu hỏi cũng được xây dựng. – MurifoX

+2

Tôi đoán nó bị đóng băng vì mỗi kết hợp 5 chữ cái bạn đang đọc từng dòng của một tệp lớn. Ít nhất tôi giả sử một danh sách từ của tiếng Anh là khá lớn. Tôi không rõ bạn đang sử dụng tệp nào. Dù sao, những gì bạn đang cố gắng làm chỉ mất rất nhiều tài nguyên (thời gian và bộ nhớ) và đó là lý do tại sao chương trình bị đóng băng. – Mischa

+0

'a.permutation (5)' kết quả trong 55440 từ có thể có năm chữ cái. Tôi không có bao nhiêu từ trong từ điển của bạn, nhưng hãy nói 100000 (đó là một ước tính rất thấp). Điều này sẽ dẫn đến một lần lặp chạy hơn 5 tỷ lần (!). – Mischa

Trả lời

1

này làm việc cho tôi bằng cách sử dụng tiếng anh.0 tập tin trên trang đó (xin lỗi, tôi không thể tìm thấy các tập tin cụ thể mà bạn đề cập):

a = %w[b a h s v i e y k s a l d n] 
dict = {} 
a.permutation(5).each do |p| 
    dict[p.join('')] = true 
end 

File.open('english.0').each_line do |line| 
    line.chomp!.downcase! 
    puts line if dict[line] 
end 

Cấu trúc nên được khá rõ ràng - Tôi xây dựng từ điển của hoán vị lên phía trước trong một hash khổng lồ (có thể bạn cần để xem lại điều này tùy thuộc vào kích thước đầu vào, nhưng bộ nhớ là giá rẻ những ngày này), và sau đó tôi đã sử dụng thực tế là đầu vào là "một từ trên mỗi dòng" để chỉ cần nhập vào băm đó.

Cũng lưu ý, trong phiên bản của mình, tôi chỉ đọc qua tệp một lần. Trong máy của bạn, bạn quét tập tin một lần trên mỗi hoán vị, và có hàng ngàn hoán vị.

+0

Điều này thực hiện. Cảm ơn Dave! – grandinero

2

Bạn hiện không thực sự sử dụng cụm từ thông dụng ở đây. Chương trình của bạn rất không hiệu quả, không chỉ vì bạn đang mở lại tệp cho từng hoán vị đơn lẻ như đã được chỉ ra (và có 55k trong số đó!); nhưng trên tất cả vì tất cả những gì bạn muốn làm là

/^[bahsvieyksa]{5}$/ 

cho mỗi dòng của tệp.

tôi như vậy, xin đề nghị:

File.open('2of4brif.txt').each_line do |line| 
    puts line if line.match(/^[bahsvieyksa]{5}$/) 
end 

như một hiệu quả hơn thay thế

+0

Trong khối mã thứ hai của bạn, bạn bỏ qua {5} từ regexp. Và khi tôi thử mã này, nó không đóng băng nhưng không in được gì cả. – grandinero

+0

Được rồi, tôi đã tìm ra lý do tại sao nó không đến với bất kỳ đầu ra nào: nó cần 'line.chomp!'. Nhưng ngay cả sau đó, nó không làm điều đúng. Ví dụ, nó đến với "hiểu biết" mặc dù chỉ có một v trong bộ ký tự. Tôi không biết nhiều về các biểu thức thông thường, vì vậy có thể bạn có thể chỉ cho tôi cách khắc phục điều đó trong mã của bạn. – grandinero

+0

Có. Trước tiên, tôi đã viết một nhận xét dài giải quyết rằng vì nhận xét của riêng bạn không hiển thị trên màn hình của tôi. Tóm lại, tôi sẽ chỉ nói mã của tôi đã làm những gì bạn nói bạn muốn, không phải những gì bạn thực sự muốn :-) Câu trả lời của Dave ở trên thực sự là những gì bạn muốn. –

0

đơn giản là chỉ cần đếm số lần xuất hiện của mỗi char và so sánh:

a = %w[b a h s v i e y k s a l d n] 
File.read('2of4brif.txt').split("\n").each do |line| 
    puts line if line.size == 5 && line.chars.all?{|x| line.count(x) <= a.count(x)} 
end 
0

Đối với tôi sau đây làm việc ra

File.open('file.txt').each_line do |line| 
    puts line if line[/<regexp>/] 
end 
Các vấn đề liên quan