2

これは他の質問から派生したものです。私たちが持っている場合:

const std::string& S = ...;
int freq[CHAR_MAX-CHAR_MIN+1]={0};

次の 4 つのループは同等ですか? あなたは何が好きですか?

for (int           c: S) ++freq[c-CHAR_MIN];  // (1)
for (char          c: S) ++freq[c-CHAR_MIN];  // (2)
for (unsigned      c: S) ++freq[c];           // (3) <-- BAD!
for (unsigned char c: S) ++freq[c];           // (4)
4

3 に答える 3

1

これを適切に一般化します。

#include <limits>
#include <vector>

template <typename C, typename T = typename C::value_type>
  std::vector<unsigned> histogram(C const& container)
{
    std::vector<unsigned> result(std::numeric_limits<T>::max() - std::numeric_limits<T>::min());
    for(auto& el : container)
        result[el - std::numeric_limits<T>::min()]++;

    return result;
}

T現在、これにより、 (入力の長さに関係なく)大きな要素タイプの結果ベクトルが不必要に大きくなります。マップの使用を検討してください。

// for very large char types, consider
#include <map>

template <typename C, typename T = typename C::value_type>
  std::map<T, unsigned> histogram_ex(C const& container)
{
    std::map<T, unsigned> result;

    for(auto& el : container)
        result[el]++;

    return result;
}

使用のいくつかのデモンストレーション:

#include <algorithm>
#include <string>
#include <iostream>

int main()
{
     auto v = histogram   (std::string ("hello world"));
     auto m = histogram_ex(std::wstring(L"hello world"));

     std::wcout << L"Sum of frequencies: " << std::accumulate(v.begin(), v.end(), 0) << "\n";

     for (auto p : m)
         std::wcout << L"'" << p.first << L"': " << p.second << L'\n';
}

版画:

Sum of frequencies: 11
' ': 1
'd': 1
'e': 1
'h': 1
'l': 3
'o': 2
'r': 1
'w': 1

すべて見る

于 2013-08-02T12:21:34.283 に答える