我想开发一个很小的脚本,该脚本读取一个句子并在控制台中生成n-gram图形的输出。
这是一个例子
Example
"Show me the code."
Returns
[
"Show",
"Show me",
"Show me the",
"Show me the code",
"me",
"me the",
"me the code",
"the",
"the code",
"code"
]
这是我的代码:
defmodule M do
def main do
sentence = IO.gets("What is the sentence : ")
ls = String.split(sentence)
lsSize = length(ls)
Enum.each 0..lsSize , fn(x) ->
posNew = x+1
IO.puts Enum.at(ls,x)
Enum.each posNew..lsSize , fn(y) ->
currentWord = Enum.join([Enum.at(ls,x), Enum.at(ls,y)], " ")
IO.puts(currentWord)
end
end
end
end
我唯一得到的是:
What is the sentence : one two three
one
one two
one three
one
two
two three
two
three
three
您能帮我吗?我不明白为什么currentCode的值未在Enum.each外部更新并被重置。 我是erlang和Elixir的新手,这就是为什么我无法理解其中的问题。
谢谢!
答案 0 :(得分:1)
那是因为您一次只连接两个单词。您对Enum.join的调用在这里仅将x
和y
位置的单词连接在一起,而并非全部他们之间的话:
Enum.join([Enum.at(ls,x), Enum.at(ls,y)], " ")
您需要连接该范围内的所有单词:
Enum.join(Enum.slice(ls, x, y), " ")
此外,您的代码还存在其他一些错误。 在这里,您可以将代码分解为较小的方法,以实现您要执行的操作:
defmodule NGram do
def run do
"Enter sentence: "
|> IO.gets
|> String.trim
|> String.split(" ")
|> build
|> Enum.map(&IO.puts/1)
:ok
end
def build(words) do
words
|> pre_walk
|> Enum.map(&String.split(&1, " "))
|> Enum.map(&post_walk/1)
|> List.flatten
end
defp pre_walk(words) do
length = length(words)
Enum.map(0..(length-1), fn i ->
words
|> Enum.slice(i, length)
|> Enum.join(" ")
end)
end
defp post_walk(subwords) do
Enum.map(1..length(subwords), fn i ->
subwords
|> Enum.slice(0, i)
|> Enum.join(" ")
end)
end
end