Word 解析器脚本和实现记忆
Word parser script and implementing memoization
描述
给定一个字典,我的程序生成两个输出文件,'sequences.txt' 和 'words.txt'。
- 'sequences' 包含四个字母 (A-z) 的每个序列,这些字母恰好出现在字典的一个单词中,每行一个序列。
- 'words' 将包含包含序列的相应单词,顺序相同,每行一个。
例如,给定的 spec/fixtures/sample_words.txt
字典仅包含
arrows
carrots
give
me
输出应该是:
'sequences' 'words'
carr carrots
give give
rots carrots
rows arrows
rrot carrots
rrow arrows
当然,'arro' 不会出现在输出中,因为它是
发现不止一个字。
到目前为止我想出了什么
项目结构:
├── Gemfile
├── Gemfile.lock
├── examples
│ └── dictionary.txt
├── lib
│ └── word_sequence_parser.rb
├── main.rb
├── output
├── readme.md
└── spec
├── fixtures
│ └── sample_words.txt
└── word_sequence_parser_spec.rb
到运行脚本:
ruby main.rb examples/dictionary.txt
main.rb
require_relative 'lib/word_sequence_parser.rb'
dict_path = ARGV.shift
if dict_path.nil?
dict_path = 'spec/fixtures/sample_words.txt'
end
parser = WordSequenceParser.new(dict_path)
# step 1 - Opens dictionary file and generates a new set of words
parser.set
# step 2 - Parses word sequences
parser.sequence
# step 3 - Prints to files in ./output
parser.dump_text
有效的脚本
word_sequence_parser.rb
require 'set'
class WordSequenceParser
def initialize(path)
@path = path
end
def set
set = Set.new
File.open(@path) do |f|
f.each_line do |line|
set.add(line.chomp.downcase)
end
end
set
end
def sequence
sequences = Set.new
words = Set.new
to_remove = Set.new
set.each do |w|
letters = w.split(//)
letters.each_cons(4) do |seq|
s = seq.join
if !words.add?(s)
to_remove.add(s)
end
sequences.add( {seq: s, word: w} )
end
end
sequences.delete_if { |hash| to_remove.include?(hash[:seq]) }
end
def dump_text
output_s = File.open( 'output/sequences.txt', 'w' )
output_w = File.open( 'output/words.txt', 'w' )
sequence.each do |hash|
output_s.puts("#{hash[:seq]}")
output_w.puts("#{hash[:word]}")
end
output_s.close
output_w.close
end
end
我对剧本的记忆不起作用
require 'set'
class WordSequenceParser
def initialize(path)
@path = path
end
def set
set = Set.new
File.open(@path) do |f|
f.each_line do |line|
set.add(line.chomp.downcase)
end
end
set
end
def memoize
@set = set
end
def sequence
sequences = Set.new
words = Set.new
to_remove = Set.new
@set.each do |w|
letters = w.split(//)
letters.each_cons(4) do |seq|
s = seq.join
if !words.add?(s)
to_remove.add(s)
end
sequences.add( {seq: s, word: w} )
end
end
sequences.delete_if { |hash| to_remove.include?(hash[:seq]) }
end
def dump_text
output_s = File.open( 'output/sequences.txt', 'w' )
output_w = File.open( 'output/words.txt', 'w' )
sequence.each do |hash|
output_s.puts("#{hash[:seq]}")
output_w.puts("#{hash[:word]}")
end
output_s.close
output_w.close
end
end
我在尝试 运行 脚本时收到此错误消息。
../word_sequence_parser.rb:29:in `sequence': undefined method `each' for nil:NilClass (NoMethodError)
from main.rb:15:in `<main>'
我已经阅读了 Justin Weiss' article on memoization 并且大部分都明白了。只是很难将这种技术应用到我已经写过的东西中。
它不起作用,因为您从不调用 memoize,所以 @set 永远不会被初始化。
然而这里真正的问题是,没有什么可以记忆的。
您的原始代码看起来很不错,如果您考虑它是如何工作的,没有任何代码的冗余执行。每行执行一次,或者如果多次执行,returns 不同的值。
因此记忆没有意义。
假设您想多次调用 dump_text(或只是序列),那么您肯定希望按如下方式记忆序列:
def sequence
@sequence ||= begin
sequences = Set.new
words = Set.new
to_remove = Set.new
set.each do |w|
letters = w.split(//)
letters.each_cons(4) do |seq|
s = seq.join
if !words.add?(s)
to_remove.add(s)
end
sequences.add( {seq: s, word: w} )
end
end
sequences.delete_if { |hash| to_remove.include?(hash[:seq]) }
end
end
这只会执行一次你原来的序列计算代码,然后分配@sequence。对@sequence 的每一次调用都会重用已经计算出的@sequence 的值(因为它现在不是零。)
我喜欢这个问题,因为这是 第一件事 我记得我的公司开始使用 ruby。我们有一位顾问重做了很多旧的 asp.net 代码,他在方法中有这些 @foo ||= ... 表达式,这是我以前从未见过的。
描述
给定一个字典,我的程序生成两个输出文件,'sequences.txt' 和 'words.txt'。
- 'sequences' 包含四个字母 (A-z) 的每个序列,这些字母恰好出现在字典的一个单词中,每行一个序列。
- 'words' 将包含包含序列的相应单词,顺序相同,每行一个。
例如,给定的 spec/fixtures/sample_words.txt
字典仅包含
arrows
carrots
give
me
输出应该是:
'sequences' 'words'
carr carrots
give give
rots carrots
rows arrows
rrot carrots
rrow arrows
当然,'arro' 不会出现在输出中,因为它是 发现不止一个字。
到目前为止我想出了什么
项目结构:
├── Gemfile
├── Gemfile.lock
├── examples
│ └── dictionary.txt
├── lib
│ └── word_sequence_parser.rb
├── main.rb
├── output
├── readme.md
└── spec
├── fixtures
│ └── sample_words.txt
└── word_sequence_parser_spec.rb
到运行脚本:
ruby main.rb examples/dictionary.txt
main.rb
require_relative 'lib/word_sequence_parser.rb'
dict_path = ARGV.shift
if dict_path.nil?
dict_path = 'spec/fixtures/sample_words.txt'
end
parser = WordSequenceParser.new(dict_path)
# step 1 - Opens dictionary file and generates a new set of words
parser.set
# step 2 - Parses word sequences
parser.sequence
# step 3 - Prints to files in ./output
parser.dump_text
有效的脚本
word_sequence_parser.rb
require 'set'
class WordSequenceParser
def initialize(path)
@path = path
end
def set
set = Set.new
File.open(@path) do |f|
f.each_line do |line|
set.add(line.chomp.downcase)
end
end
set
end
def sequence
sequences = Set.new
words = Set.new
to_remove = Set.new
set.each do |w|
letters = w.split(//)
letters.each_cons(4) do |seq|
s = seq.join
if !words.add?(s)
to_remove.add(s)
end
sequences.add( {seq: s, word: w} )
end
end
sequences.delete_if { |hash| to_remove.include?(hash[:seq]) }
end
def dump_text
output_s = File.open( 'output/sequences.txt', 'w' )
output_w = File.open( 'output/words.txt', 'w' )
sequence.each do |hash|
output_s.puts("#{hash[:seq]}")
output_w.puts("#{hash[:word]}")
end
output_s.close
output_w.close
end
end
我对剧本的记忆不起作用
require 'set'
class WordSequenceParser
def initialize(path)
@path = path
end
def set
set = Set.new
File.open(@path) do |f|
f.each_line do |line|
set.add(line.chomp.downcase)
end
end
set
end
def memoize
@set = set
end
def sequence
sequences = Set.new
words = Set.new
to_remove = Set.new
@set.each do |w|
letters = w.split(//)
letters.each_cons(4) do |seq|
s = seq.join
if !words.add?(s)
to_remove.add(s)
end
sequences.add( {seq: s, word: w} )
end
end
sequences.delete_if { |hash| to_remove.include?(hash[:seq]) }
end
def dump_text
output_s = File.open( 'output/sequences.txt', 'w' )
output_w = File.open( 'output/words.txt', 'w' )
sequence.each do |hash|
output_s.puts("#{hash[:seq]}")
output_w.puts("#{hash[:word]}")
end
output_s.close
output_w.close
end
end
我在尝试 运行 脚本时收到此错误消息。
../word_sequence_parser.rb:29:in `sequence': undefined method `each' for nil:NilClass (NoMethodError)
from main.rb:15:in `<main>'
我已经阅读了 Justin Weiss' article on memoization 并且大部分都明白了。只是很难将这种技术应用到我已经写过的东西中。
它不起作用,因为您从不调用 memoize,所以 @set 永远不会被初始化。
然而这里真正的问题是,没有什么可以记忆的。
您的原始代码看起来很不错,如果您考虑它是如何工作的,没有任何代码的冗余执行。每行执行一次,或者如果多次执行,returns 不同的值。
因此记忆没有意义。
假设您想多次调用 dump_text(或只是序列),那么您肯定希望按如下方式记忆序列:
def sequence
@sequence ||= begin
sequences = Set.new
words = Set.new
to_remove = Set.new
set.each do |w|
letters = w.split(//)
letters.each_cons(4) do |seq|
s = seq.join
if !words.add?(s)
to_remove.add(s)
end
sequences.add( {seq: s, word: w} )
end
end
sequences.delete_if { |hash| to_remove.include?(hash[:seq]) }
end
end
这只会执行一次你原来的序列计算代码,然后分配@sequence。对@sequence 的每一次调用都会重用已经计算出的@sequence 的值(因为它现在不是零。)
我喜欢这个问题,因为这是 第一件事 我记得我的公司开始使用 ruby。我们有一位顾问重做了很多旧的 asp.net 代码,他在方法中有这些 @foo ||= ... 表达式,这是我以前从未见过的。