3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Elixir]文字列中のパタン出現頻度をカウントする

Last updated at Posted at 2020-08-14

Elixirで文字列の頻度を求めたいと思って調べた際の実装メモです

求めたいパタンが1通りの場合

例:関数alter_altarは入力seqについて、Rの出現頻度を求めています。

  def alter_altar(_n, seq) do
    r_count = Regex.scan(~r/R/, seq)
            |> Enum.count

Regex.scanについては下記を参照
https://hexdocs.pm/elixir/Regex.html#scan/3

説明:
Regex.scan(~r/求めたいパタン/)とします。
Regex.scanを実行したままだと、マッチしたパタンを要素とするリストになっています。
例:入力WWWRRRWWWRRRRRRRW
に対して、Regex.scan(~r/R/)を実行すると以下になります。

[["R"], ["R"], ["R"], ["R"], ["R"], ["R"], ["R"], ["R"], ["R"], ["R"]]

このため、Enum.countで頻度を求めます。
Enum.countについては下記を参照。
https://hexdocs.pm/elixir/Enum.html#count/1

求めたいパタンが複数の場合

上記を複数パタンに拡張します。※ほぼほぼBag of Wordsです

defmodule Main do
  def frequency_dist(patterns, seq) do
    frequency_dist = Enum.map(patterns, fn pattern -> Regex.scan(~r/#{pattern}/, seq) end)
                |> Enum.map(fn x -> Enum.count(x) end)
  end

 def main do
    patterns = IO.read(:line) |> String.trim() |> String.split()
    seq = IO.read(:line) |> String.trim()
    IO.inspect frequency_dist(patterns,seq)
 end
end

関数frequency_distは頻度を求めたい文字列パタンのリストpatternsと対象文字列seqの入力に対し、出現頻度のリストを返します。
例:
入力:
W R E F
WERWWWRRRRRRRRRRRRRRRR
に対して、以下の結果になります。

[4, 17, 1, 0]

補足:

同じようにパタンを求める関数として、Regex.runがあります。
https://hexdocs.pm/elixir/Regex.html#run/3

しかし、Regex.runはマッチした最初のパタンを返します。
例:入力WWWRRRWWWRRRRRRRW
に対して、Regex.run(~r/R/)を実行すると以下になります。

["R"]

こちらは出現頻度のカウントではなく、パタンの存在判定等に使えそうです。

サンプルは以下の問題を説いたときのものです
D - Alter Altar

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?