2016-10-30 2 views
-2

Хорошо, поэтому мне интересно, как бы я хотел создать ключ карты из двух словной строки (bigram). Например, строка «Это только тест». будет содержать битрамы «это», «только», «только» и «тест».Bigrams как ключи карты в C++

Я думаю использовать make_pair, но что-то говорит мне, что это может привести к тому, что эти биграммы будут созданы не по порядку. Это будет так? Если нет, будет ли этот подход к парному пути на правильном пути?

+0

Вы можете использовать практически любую структуру данных для хранения биграма. A 'std :: vector ', 'std :: tuple '/'std :: pair ', 'std :: list 'и т. Д. - все действительные и разумные варианты в зависимости от того, что вы хотите с ними делать. – erip

ответ

1

Я бы порекомендовал 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.

+0

Спасибо за помощь! Ценю вашу помощь! –

Смежные вопросы