28
17

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 5 years have passed since last update.

C++ で重複削除を行う関数 unique の使い方 [ABC143 C問題]

Last updated at Posted at 2019-10-20

重複削除を行うC++ の STL 関数 unique の使い方のメモ。
問題はここ:ABC143 C問題

問題の趣旨は
aabbbbaaca のような文字列が与えられて、隣合う同じ文字を一つにまとめて abaca のようにしたら何文字か?」
という感じ。

#コンテスト中に提出したコード
unique のことは知らなかったのでコンテスト中は以下のようなコードを書いた。

submit.cpp
#include <bits/stdc++.h>
using namespace std;

int main(){
  int n; cin >> n;
  string s; cin >> s;

  int ans = 0;
  int i = 0;
  while(i < n){
    char c = s[i];
    ans++;
    while(s[i] == c){
      i++;
      if(i >= n) break;
    }
  }
  cout << ans << '\n';
}

見にくいしスマートじゃない…

#unique を使った解法
公式の解答では以下のようなスマートなコードが示されている。

smart.cpp
#include <bits/stdc++.h>
using namespace std;

int main(){
  int n; cin >> n;
  string s; cin >> s;

  s.erase(unique(s.begin(), s.end()), s.end());
  cout << s.size() << '\n';
}

確かにスマートだけど unique を知らないから何をしているのかよく分からん…

#unique の使い方

unique は重複削除を行いたい文字列をsとすると
unique(s.begin(), s.end())
とすることで文字列 s を
aabbbcddaaaabcda?????? (? はゴミ)
とし、最初の ? を指すポインタを返す。
この返り値を利用してゴミを erase すれば重複削除の完成!

unique.cpp
#include <bits/stdc++.h>
using namespace std;

int main(){
  string s = "aabbbcddaaa";

  auto n = unique(s.begin(), s.end());
  // これで s = abcda となってほしい
  cout << s << '\n';//しかし s = abcda?????? とゴミが残る

  // unique は返り値として ? の先頭を指すポインタを返す
  // そこで n から最後まで erase すれば完成
  s.erase(n,s.end());
  cout << s << '\n';
}

これを全部まとめてしまえば

smart.cpp
#include <bits/stdc++.h>
using namespace std;

int main(){
  int n; cin >> n;
  string s; cin >> s;

  s.erase(unique(s.begin(), s.end()), s.end());
  cout << s.size() << '\n';
}

となるわけですね。
ちなみに unique はもちろん配列にも同じ用法で使える。

28
17
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
28
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?