3
3

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.

文字列Aから文字列Bを検索する(重複カウント)

Posted at

とある文字列から、とある文字列を検索したい

以下のような文字列「t」から「s」を検索したいんですよ。

filename.rb
s = 'AA'
t = 'abdeeAAbAAAbfde'

普通に、「へっ、countメソッドでいけるやん」と思った馬鹿な私。

filename.rb
s = 'AA'
t = 'abdeeAAbAAAbfde'
puts t.count(s)

# 期待する出力 ➡︎ 3
# 実際の出力 ➡︎ 5

いや、これ普通にAの数を数えとるだけやんけー。
countメソッドだと引数にまとまった文字列を与えても1文字・1文字を検索しちゃうみたい。

重複してもいいから文字列AAを検索したい!

つまり、

  1. 左から数えて最初のAA
  2. AAAの最初のAA(AA←これ A)
  3. 最後のAA(A これ→AA)

以上の3個を数えたいんですよ。
(伝われ、、、!笑)

どうすればいいのか

噛み砕いて考えると文字列abdeeAAbAAAbfdeを
ab bd de ee eA AA Ab bA AA AA Ab bf fd deに分割して
文字列AAに合致するかどうかを検証してtrueなら数えて、falseなら数えなければ良いのだ。

※ポイント
文字列のインデックスを上手く利用して範囲指定をする

実際のコード

filename.rb

s = 'AA'
t = 'abdeeAAbAAAbfde'

result = 0

(0..(t.size - s.size)).each do |i|
  substring = t.slice(i, s.size)


  if substring == s
    result += 1
  end
end

puts result

# 期待する出力 ➡︎ 3
# 実際の出力 ➡︎ 3

出来た!

##知らなければいけないこと

###sizeメソッド
stringクラスで使用すると文字列を数えることが出来る。(Arrayクラスで使うと要素数を数える)lengthメソッドと一緒。

###sliceメソッド
引数で範囲を指定すると、その範囲の文字列を返す。

##反省点
「必要なデータをどのように切り取るか」という部分が今回のミソだと思う。パッと出てこないところがまだまだアルゴリズムを生み出す頭になっていないのだと思う。んー難しい。

3
3
1

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
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?