1
4

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 1 year has passed since last update.

Swiftで二つの文字列を比較し、片方の文字列の構成要素だけでもう一方の文字列が構成可能かをチェックするアルゴリズム

Last updated at Posted at 2024-01-17

概要

383. Ransom Noteを解いているときに書いた処理をもしかしたらどこかで使うかも?と思ったので記事として残しておきます。

詳細

以下のようなケースで使用できます。

ransomNoteとmagazineの2つの文字列が与えられたとき、ransomNoteがmagazineの文字を使って構成できる場合はtrueを、そうでない場合はfalseを返す。
magazineの各文字はransomNoteで一度しか使用できない。

今回書いた方法はDictionaryを用いた処理、そしてreduce関数を用いた処理です。

まずはDictionaryを用いた例です。
こちらは単純な考え方で、Dictionary内にmagazineの内容を詰め込んだ後にransomNote内との照会を行う、という内容になります。
基本的なデータ構造を用いている分、記述がしやすい反面、個人的にはちょっと記述量が多く、やや冗長に感じます。

Dictionaryを用いた例
class Solution {
    // ransomNoteの文字列がmagazine文字列のみで構成されているかを確認する関数
    func canConstruct(_ ransomNote: String, _ magazine: String) -> Bool {
        var counter = [Character: Int]()
        // Dictionaryのcounter内に`magazine`の内容を詰める処理
        for m in magazine{
            if let count = counter[m]{
                counter[m] = count+1
            }else{
                counter[m] = 1
            }
        }

        // ransomNote内とDictionaryのcounter内の照合を行い、存在していて、かつカウントが0よりも大きい場合にはカウントの減算を行い、処理を継続する
        for r in ransomNote{
            if let count = counter[r],count > 0{
                counter[r] = count-1
            }else{
                return false
            }
        }
        return true
    }
}

次にreduce関数を用いた例です。
こちらも基本的な考え方は先述の内容と同じですが、reduce関数を用いた処理を関数として外出ししており、メイン処理を行う関数がスッキリしています。
コードの量がスッキリし、読みやすくなった印象です。

reduce関数を用いた例
class Solution {

    // ransomNoteの文字列がmagazine文字列のみで構成されているかを確認する関数
    func canConstruct(_ ransomNote: String, _ magazine: String) -> Bool {
       var magazineWordCount = countCharacters(magazine)
       for r in ransomNote {
           if let count = magazineWordCount[r],count > 0{
               magazineWordCount[r] = count - 1
           }else{
               return false
           }
       }
       return true
    }

    // reduce関数を用いて関数内に存在する文字とその文字が登場する回数をカウントする関数
    func countCharacters(_ str:String) -> [Character:Int]{
        return str.reduce(into: [:]) { counts,char in
            counts[char,default:0] += 1
        }
    }
}

ただ、このようなコードを書いておいてなんですが、私のSwiftの習熟度的には何も見ずにいきなりreduce関数を使った処理を書いてと言われると困ると思ったので、記事として残しておきます!

1
4
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
1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?