空腹おやじのログと備忘録

VBA(主にExcel)でいろいろな実験的な事とか、Linuxのコマンドとか設定とかについて忘れないように、あれこれと・・・

【C++】Twitter のお題 「魚の数を数えろ!」を正規表現を使って解いてみた

ゴールデンウィークに行われた、Twitter のお題
「魚の数を数えろ!」
「魚の数を数えろ! 蟹バージョン」
を今更ながら、C++正規表現を使って解いてみた。

複数のマッチがある場合の繰り返し処理がわからず、あちこち探してやっと完成。
結局、開始位置をイテレーターで、移動させ、マッチしなくなるまでループさせるという方法に落ち着いた。

他にもっと良い方法をご存知の方がいらっしゃいましたら、教えて下さい。

#include <iostream>
#include <string>
#include <unordered_map>
#include <regex>

using namespace std;

void    countFish();
void    countCrab();

int main()
{
    wcout.imbue(locale("japanese"));

    wcout << L"Fish" << endl;
    countFish();

    wcout << L"\nCrab" << endl;
    countCrab();

    return 0;
}

void    countFish()
{
    const wstring sFish{ L"鯵鯖鯵鯖鯵鯖鯵鯖鯵鯖鯵鯖鯵鯖鯵鯖鯵鯖鯵" };

    unordered_map<wstring, int> m;

    for (auto i = 0; i < sFish.length(); ++i)
        ++m[sFish.substr(i, 1)];

    for (const auto& mi : m)
        wcout << mi.first << L"::" << mi.second << endl;
}

void    countCrab()
{
    const wstring sCrab{ L"タラバガニ毛ガニタラバガニ毛ガニ越前蟹タラバガニ花咲蟹越前蟹越前蟹越前蟹ズワイガニズワイガニ越前蟹タラバガニズワイガニ" };

    unordered_map<wstring, int> m;

    wregex re(L"(?:(^|蟹|ガニ))(.+?)(蟹|ガニ)");

    wsmatch mc;

    auto it = sCrab.cbegin();
    while (regex_search(it, sCrab.cend(), mc, re))
    {
        ++m[mc[2].str() + mc[3].str()];

        it = mc.suffix().first;
    }

    for (const auto& mi : m)
        wcout << mi.first << L"::" << mi.second << endl;
}

実行結果
f:id:Z1000S:20200515222616p:plain