-1

クラスのプロジェクトでは、公開された論文を取り上げて、ストップ ワードを除外しながらテキスト単位のすべての単語のリストを作成するアルゴリズムを作成することになっています。すべての一意の単語 (テキスト全体) とその出現頻度のリストを作成しようとしています。これは、テキストの 1 行に対して作成したアルゴリズムです。

x = l[125] #Selecting specific line in the text
p = Array.new() # Assign new array to variable p
p = x.split # Split the array
for i in (0...p.length)
  if(p[i] != "the" and p[i] != "to" and p[i] != "union" and p[i] != "political")
    print p[i] + " "
  end
end
puts 

このプログラムの出力は、ストップ ワードを除いた 1 つの文 (125 行目から) です。バブルソートを使用する必要がありますか? 同じ長さの文字列をソートするように変更するにはどうすればよいですか (またはそれは無関係ですか)。

4

2 に答える 2

1

Ruby の列挙可能なクラスを実際に調べる必要があります。for x in yRubyで行うことはめったにありません。

word_list = ["the", "to", "union", "political"]
l[125].split.each do |word|
  print word + " " unless word_list.include?(word)
end

カウント、ソート、およびそれらすべてを行うために、group_by メソッドと、おそらく配列の sort_by メソッドを調べます。

于 2013-11-05T09:21:19.747 に答える
1

Ruby を初めて使用することを考えると、良いスタートを切ったと思います。バブルソートを使用する必要があるかどうかを尋ねました。単語の複数の出現をグループ化し、配列を調べてそれらをカウントすることを考えていると思います。それは機能しますが、より簡単で「Ruby に似た」アプローチが他にもいくつかあります。(つまり、言語の強力な機能を利用すると同時に、より自然になります。)

1 行で一意の単語を数えることに注目しましょう。それができれば、それを複数の行に簡単に一般化できるはずです。

最初の方法: ハッシュを使用する

最初のアプローチは、ハッシュを使用することです。 h = {}新しい空のものを作成します。ハッシュのキーは単語になり、その値は各単語が行に存在する回数になります。たとえば、「cat」という単語が 9 回出現する場合、h["cat"] = 9必要なものだけが になります。このハッシュを作成するwには、行内の各単語が既にハッシュ化されているかどうかを確認します。ハッシュ内にある場合

h[w] != nil

そうであれば、単語数をインクリメントします。

h[w] = h[w] + 1

あるいは単に

h[w] += 1

ハッシュに含まれていない場合は、次のように単語をハッシュに追加します。

h[w] = 1

つまり、次のことができます。

if h[w]
  h[w] += 1
else
  h[w] = 1
end

ここif h[w]は と同じであることに注意してくださいif h[w] != nil

実際には、これをさらに簡単にするトリックを使用できます。次のようにハッシュを作成すると:

h = Hash.new(0)

値なしで追加したキーには、デフォルト値のゼロが割り当てられます。そうすれば、単語がすでにハッシュに含まれているかどうかを確認する必要がなくなります。私たちは単に書く

h[w] += 1

wがハッシュにない場合、h[w]それを追加して に初期化し0、次に+= 1にインクリメントし1ます。かっこいいね?

これをすべてまとめましょう。仮定する

line = "the quick brown fox jumped over the lazy brown fox"

String#splitメソッドを使用して、この文字列を配列に変換します。

arr = line.split # => ["the", "quick", "brown", "fox", "jumped", \
                       "over", "the", "lazy", "brown", "fox"] 

それから

h = Hash.new(0)
arr.each {|w| h[w] += 1}
h # => {"the"=>2, "quick"=>1, "brown"=>2, "fox"=>2, "jumped"=>1, "over"=>1, "lazy"=>1} 

終わったね!

2番目の方法: メソッドを使用Enumerable#group_byする

配列、ハッシュ、またはその他のコレクションの要素をグループ化したいときはいつでも、group_byメソッドが頭に浮かぶはずです。

迅速な茶色のキツネの配列に適用group_byするために、グループ化基準を含むブロックを提供します。この場合、それは単に単語そのものです。これによりハッシュが生成されます。

g = arr.group_by {|e| e}
 # => {"the"=>["the", "the"], "quick"=>["quick"], "brown"=>["brown", "brown"], \
 #     "fox"=>["fox", "fox"], "jumped"=>["jumped"], "over"=>["over"], "lazy"=>["lazy"]} 

次に行うことは、ハッシュ値を単語の出現回数に変換することです (たとえば、convert ["the", "the"]to 2)。これを行うには、新しい空の hash を作成し、hそれにハッシュ ペアを追加します。

h = {}
g.each {|k,v| h[k] = v.size}
h # => {"the"=>2, "quick"=>1, "brown"=>2, "fox"=>2, "jumped"=>1, "over"=>1, "lazy"=>1

もう一つ

次のコード スニペットがあります。

  if(p[i] != "the" and p[i] != "to" and p[i] != "union" and p[i] != "political")
    print p[i] + " "
  end

上記のハッシュを使用して、これを少しきれいにするいくつかの方法を次に示しますh

最初の道

 skip_words = %w[the to union political] # => ["the", "to", "union", "political"] 
 h.each {|k,v| (print v + ' ') unless skip_words.include?(k)}

第二の道

 h.each |k,v|
   case k
   when "the", "to", "union", "political"
     next
   else
     puts "The word '#{k}' appears #{v} times."
   end
 end

あなたのコメントに対処するために編集します。これを試して:

p = "The quick brown fox jumped over the quick grey fox".split
freqs = Hash.new(0)
p.each {|w| freqs[w] += 1}
sorted_freqs = freqs.sort_by {|k,v| -v}
sorted_freqs.each {|word, freq| puts word+' '+freq.to_s}
=>
quick 2
fox 2
jumped 1
The 1
brown 1
over 1
the 1
grey 1

通常、ypu はハッシュをソートしません。むしろ、最初に配列に変換します。

sorted_freqs = freqs.to_a.sort_by {|x,y| v}.reverse

また

sorted_freqs = freqs.to_a.sort_by {|x,y| -v}

sorted_freqsハッシュではなく配列になりました。最後の行はそのままです。一般に、ハッシュの順序に依存しないことが最善です。実際、Ruby バージョン 1.9.2 より前では、ハッシュは順序付けされていませんでした。順序が重要な場合は、配列を使用するか、ハッシュを配列に変換してください。

そうは言っても、ハッシュ値で最小から最大に並べ替えるか、(私が行ったように) ハッシュ値の負の値で最大から最小に並べ替えることができます。Enumerable#reverseまたはがないことに注意してくださいHash#reverse。別の方法として (Ruby で猫の皮を剥ぐには常に多くの方法があります)、次のように並べ替えてv使用することもできEnumerable#reverse_eachます。

sorted_freqs.reverse_each {|word, freq| puts word+' '+freq.to_s}

最後に、最後の 2 つのステートメントをチェーンすることにより、一時変数sorted_freqs(メソッドがないために必要)を削除できます。Enumerable#sort_by!

freqs.sort_by {|k,v| -v}.each {|word, freq| puts word+' '+freq.to_s}
于 2013-11-05T08:32:06.313 に答える