このページについて

このページは、paiza ラーニング内に開設されているコンテンツ「レベルアップ問題集」で取り扱われているプログラミング課題について、独自の見解を述べたものです。

見解については、paizaラーニングの規約に基づき、許可されている範囲でのみ公開していますが、その内容については paiza とは一切関係なく、また paiza の立場を反映したものではありませんのでご注意ください。

挑戦する課題

レベルアップ問題集の文字列処理メニューから「重複の削除 (paizaランク C 相当)」を取り上げます。

以下は、問題公開 Web ページからの引用です。

問題

数字を表す文字列 S が与えられるので、 S の先頭(左側)から S を見て行ったときにその数字が現れたのが 2 回目以降の場合、その数字を削除した文字列(重複した数字を削除した文字列)を求めてください。

  • S = “1234567890” のとき
    数字に重複はないので “1234567890” が答えとなります。
  • S = “112123123412345” のとき
    “12345” が答えとなります。

    • 1 は 1 文字目に初めて現れるので、それ以降の 1 は読み飛ばします。
    • 2 は 3 文字目に初めて現れ、それ以降の 2 は読み飛ばします。
    • 3 は 6 文字目に初めて現れ、それ以降の 3 は読み飛ばします。
    • 4 は 10 文字目に初めて現れ、それ以降の 4 は読み飛ばします。
    • 5 は 15 文字目に初めて現れ、それ以降の 5 は読み飛ばします。

入力される値

  • 文字列 S が 1 行で与えられます。

期待する出力

S から数字の重複を取り除いたときにできる文字列を 1 行で出力してください。

考え方

本来であれば、Foundation の NSOrderSet を使うのが簡単な方法である。

NSOrderSet は、 Set と同じく値の重複が無いコレクションが作れる一方、 Set とは異なり代入された順番が保証される集合である。
たとえば、Playground での実行結果は次のとおりである。
しかし、paiza の Swift コンパイラでは意図した通りの実行結果が出ない(重複された値も出力される)ため、辞書型を使って既出の数字を記録させる方法で解決した。

具体的には、重複チェック用のフラグとして、 [String: Bool] の辞書を作っておく。
入力された文字列は、あらかじめ文字列の文字列として分解しておき、 for-in 文を使って1文字ずつ取り出す。

辞書の場合、与えられたキーが存在しない場合には nil を返す。したがって、キーとして取り出した文字列を与え、それが新出の文字列であれば、出力用の文字列に追加する。

解答例

リファレンス