Я бы порекомендовал std::pair
, потому что он по сути двоичный. Если есть вероятность, что вам нужны триграммы или 4 грамма, вы можете придерживаться std::tuple
, что является обобщением std::pair
(неофициально).
До тех пор, пока ваш алгоритм bigram будет правильным, заказ будет сохранен. Есть некоторые очевидные улучшения, которые могут быть сделаны, но я написал быструю реализацию здесь:
#include <iostream>
#include <vector>
#include <string>
#include <iterator>
#include <map>
#include <sstream>
#include <utility>
std::vector<std::string> tokenize(const std::string& s) {
std::istringstream iss(s);
std::vector<std::string> v{std::istream_iterator<std::string>(iss),
std::istream_iterator<std::string>()};
return v;
}
std::vector<std::pair<std::string, std::string>> make_bigrams(const std::vector<std::string>& tokens) {
std::vector<std::pair<std::string, std::string>> bigrams;
for(auto it = std::cbegin(tokens); it != std::prev(std::cend(tokens)); ++it) {
bigrams.push_back(std::make_pair(*it, *std::next(it)));
}
return bigrams;
}
std::vector<std::pair<std::string, std::string>> sentence_bigram(const std::string& s) {
const auto toks = tokenize(s);
return make_bigrams(toks);
}
int main() {
const auto& bigrams = sentence_bigram("hello, world. my name is erip");
std::map<std::pair<std::string, std::string>, int> m;
for(const auto& e: bigrams) {
std::cout << "Adding (" << e.first << "), (" << e.second << ") to the map.\n";
m[e] = 0;
}
}
и вы можете увидеть его в действии here.
Вы можете использовать практически любую структуру данных для хранения биграма. A 'std :: vector', 'std :: tuple '/'std :: pair ', 'std :: list 'и т. Д. - все действительные и разумные варианты в зависимости от того, что вы хотите с ними делать. –
erip