C++ Streams というライブラリがあります。これは、平たく言うとコンテナに対する処理を提供するもので、標準の汎用アルゴリズム、Boost.Range、PStade.Oven などの競合に当たります。
ワードカウントやります。始めは、標準のアルゴリズムを使います。
#include <algorithm>
#include <iostream>
#include <regex>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
int main() {
auto sentence = std::string("You play with the cards you're dealt... whatever that means.");
sentence = std::regex_replace(sentence, std::regex("[^a-zA-Z]"), "");
std::transform(sentence.begin(), sentence.end(), sentence.begin(), ::toupper);
const auto counts =
std::accumulate(sentence.begin(), sentence.end(), std::unordered_map<char, int>(), [](auto counts, auto word) {
counts.insert(std::make_pair(word, ++counts[word]));
return counts;
});
auto result = std::vector<std::pair<char, int>>(counts.begin(), counts.end());
std::sort(result.begin(), result.end(), [](auto a, auto b) {
return b.second < a.second;
});
std::for_each(result.begin(), result.end(), [](auto pair) {
std::cout << pair.first << ": " << pair.second << std::endl;
});
}
次に、脱アルゴリズム宣言します。
#include <iostream>
#include <regex>
#include <string>
#include <unordered_map>
#include <utility>
#include "Stream.h"
int main() {
using streams = stream::MakeStream;
const auto sentence = std::string("You play with the cards you're dealt... whatever that means.");
const auto counts =
streams::from(std::regex_replace(sentence, std::regex("[^a-zA-Z]"), ""))
.map(::toupper)
.reduce(std::unordered_map<char, int>(), [](auto counts, auto word) {
counts.insert(std::make_pair(word, ++counts[word]));
return counts;
});
streams::from(counts).sort([](auto a, auto b) {
return b.second < a.second;
})
.for_each([](auto pair) {
std::cout << pair.first << ": " << pair.second << std::endl;
});
}
唐突ですけど、C++ Streams と Boost.Asio と標準の正規表現を使ってみたかったので、ウェブスクレイピングやります。
#include <iostream>
#include <regex>
#include <string>
#include <vector>
#include <boost/asio.hpp>
#include <boost/format.hpp>
#include "Stream.h"
int main() {
using streams = stream::MakeStream;
const auto source =
streams::range(0, 3).reduce(std::string(), [](std::string source, int offset) {
boost::asio::ip::tcp::iostream stream("cpplover.blogspot.jp", "http");
stream << boost::format("GET /search?q=pdf&start=%d HTTP/1.0\r\n") % (offset * 20)
<< "Host: cpplover.blogspot.jp\r\n\r\n"
<< std::flush;
for (std::string line; std::getline(stream, line); ) {
source += line;
}
return source;
});
const auto re = std::regex("\\.pdf\">\\[(.+?)\\]");
const auto begin = std::sregex_iterator(source.begin(), source.end(), re);
const auto end = std::sregex_iterator();
streams::from(begin, end).for_each([](auto s) {
std::cout << s[1].str() << std::endl;
});
}
$ g++ main.cpp -std=c++14 -lboost_system -I ./Streams/source/
楽しい! ✌(’ω’✌ )三✌(’ω’)✌三( ✌’ω’)✌