Dizgeyle temsil edilen belirli bir Word'ü ararken, muhtemelen map gibi bir şeye bakmak istersiniz. Basit bir sonuç birliği oluşturmak için muhtemelen set. Bu uygulama, son derece istenen bir nihai uygulamadan ziyade bir gösteri olarak yazılmıştır (c.f.özensiz ifade ayrıştırma). bu bir
#include <vector>
#include <map>
#include <set>
#include <iostream>
#include <string>
typedef std::string IDdoc;
typedef int position;
typedef std::pair<IDdoc,position> Occurrence;
typedef std::vector<Occurrence> OccurrencesOfWord;
typedef std::map<std::string /*word*/, OccurrencesOfWord> Dictionary;
typedef std::set<IDdoc> Matches;
bool findMatchesForPhrase(const std::string& phrase, const Dictionary& dictionary, Matches& matches)
{
size_t pos = 0;
size_t len = 0;
while (pos < phrase.length()) {
size_t end = phrase.find(' ', pos);
size_t len = ((end == phrase.npos) ? phrase.length() : end) - pos;
std::string word(phrase, pos, len);
pos += len + 1; // to skip the space.
// ignore words not in the dictionary.
auto dictIt = dictionary.find(word);
if (dictIt == dictionary.end())
continue;
auto& occurrences = dictIt->second; // shortcut/alias,.
for (auto& occurIt : occurrences) {
// Add all the IDdoc's of this occurence to the set.
matches.insert(occurIt.first);
}
}
return !matches.empty();
}
void addToDictionary(Dictionary& dict, const char* word, const char* doc, int position)
{
dict[word].push_back(std::make_pair(std::string(doc), position));
}
int main(int argc, const char** argv)
{
std::string phrase("pizza is life");
Dictionary dict;
addToDictionary(dict, "pizza", "book1", 10);
addToDictionary(dict, "pizza", "book2", 30);
addToDictionary(dict, "life", "book1", 1);
addToDictionary(dict, "life", "book3", 1);
addToDictionary(dict, "goat", "book4", 99);
Matches matches;
bool result = findMatchesForPhrase(phrase, dict, matches);
std::cout << "result = " << result << std::endl;
for (auto& ent : matches) {
std::cout << ent << std::endl;
}
return 0;
}
Çevrimiçi demo: http://ideone.com/Zlhfua
değişiklikleri ele almak Takip:
while(i < SIZE_VECTOR_ONE && j < SIZE_VECTOR_TWO)
{
if (ID_doc_one < ID_doc_two)
{
ID_doc_one = v1[++i].first;
"SIZE_VECTOR 1" Diyelim biri olduğu anlamına gelir 1'dir vektörde eleman, eleman [0]. ID_doc_one 0'dır ve ID_doc_two sonra, geçersiz
if (0 < 1) {
ID_doc_one = v1[1].first;
1 ise. Bu tür kırık görünüyor,
while (oneIt != v1.end() && twoIt != v2.end()) {
if (oneIt->first < twoIt->first) {
++oneIt;
continue;
} else if (*twoIt < *oneIt) {
++twoIt;
continue;
}
// same documentId in both lists, snag positions.
...
}
İleri:
else {
} // To avoid "out of range" errors <-- but also ends the "else"
if (i < SIZE_VECTOR_ONE - 1)
ID_doc_one = v1[++i].first;
if (j < SIZE_VECTOR_TWO - 1)
ID_doc_two = v2[++j].first;
}
Ve senin de aynı belgeyi ancak birden pozisyonları varsa ne olur acaba Sen yineleyicinızı veya işaretçileri kullanarak daha iyi olabilir?
Bu gelecek sirke seçici, ancak ikinci kelime pozisyonundan sonra ise (" o bunu diyebilirsiniz bu yazmak için çok daha net görünüyor
WordPosition_t pos_one = v1[i].second;
WordPosition_t pos_two = v2[j].second;
// The words make a phrase! Return pos_two for the next intersection finding step
if (pos_one + 1 == pos_two)
ayrıştırmak için bana uzun bir zaman aldı birinci sözcük): Her iki maddeleri ortak içine parçası kaldırma için, mantıklı olurdu i ve j, ve güncelleme ID_doc_one ve iki artırmak için tasarlanmıştır ortaya çıktı çünkü
WordPosition_t posFirstWord = v1[i].second;
WordPosition_t posSecondWord = v2[j].second;
// The words make a phrase! Return pos_two for the next intersection finding step
if (posSecondWord == posFirstWord + 1)
Bu, sonraki bir parçası, bir tür kafa karıştırıcı if bloğundan sonra bölüm, ancak yine else {}
bunu yaptı aslında ne yaptığınızı söylemek zor. Her iki diziler maç ne zaman pos_two kullanırken neden ifade aslında pos_one yerinde bulundu beri
if (pos_one + 1 == pos_two)
{
intersection.push_back(make_pair(ID_doc_one,pos_two));
ID_doc_one = v1[++i].first;
ID_doc_two = v2[++j].first;
}
else {
} // To avoid "out of range" errors
if (i < SIZE_VECTOR_ONE - 1)
ID_doc_one = v1[++i].first;
if (j < SIZE_VECTOR_TWO - 1)
ID_doc_two = v2[++j].first;
}
, her zaman, ben de emin değilim, i ve j hem bu şart değil artırmak istediğiniz?
Bu
bunu yazdım şekli şöyledir:
#include<iostream>
#include<map>
#include<vector>
#include<string>
typedef std::string Word_t;
typedef unsigned int WordPosition_t;
typedef unsigned int IDdocument_t;
typedef std::pair<IDdocument_t, WordPosition_t> DocumentPosition_t;
typedef std::vector<DocumentPosition_t> WordReferences_t;
WordReferences_t _intersect_two_words(const WordReferences_t& v1, const WordReferences_t& v2)
{
// all the locations where the words occur one after the other.
WordReferences_t intersection;
auto firstIt = v1.begin();
auto secondIt = v2.begin();
while (firstIt != v1.end() && secondIt != v2.end())
{
if (firstIt->first < secondIt->first)
{
++firstIt;
continue;
}
// find the second word in the same document and AFTER the first word.
if (secondIt->first < firstIt->first || secondIt->second < firstIt->second + 1)
{
++secondIt;
continue;
}
// first word wasn't just before the second, it's not a phrase.
if (secondIt->second > firstIt->second + 1)
{
++firstIt;
continue;
}
// We found a phrase.
intersection.emplace_back(*firstIt);
++firstIt;
++secondIt;
}
return intersection;
}
int main()
{
WordReferences_t v1, v2;
v1.push_back(std::make_pair(10, 5));
v1.push_back(std::make_pair(10, 25));
v1.push_back(std::make_pair(11, 10));
v1.push_back(std::make_pair(12, 1));
v1.push_back(std::make_pair(12, 11));
v1.push_back(std::make_pair(12, 21));
v1.push_back(std::make_pair(12, 31));
v1.push_back(std::make_pair(15, 11));
v1.push_back(std::make_pair(100, 1));
v1.push_back(std::make_pair(100, 11));
v1.push_back(std::make_pair(100, 21));
v1.push_back(std::make_pair(101, 11));
v1.push_back(std::make_pair(102, 11));
v1.push_back(std::make_pair(102, 13));
v1.push_back(std::make_pair(102, 14));
v1.push_back(std::make_pair(103, 11));
v1.push_back(std::make_pair(103, 13));
v2.push_back(std::make_pair(10, 11));
v2.push_back(std::make_pair(12, 10));
v2.push_back(std::make_pair(12, 40));
v2.push_back(std::make_pair(16, 11));
v2.push_back(std::make_pair(100, 12)); // match
v2.push_back(std::make_pair(101, 12)); // match
v2.push_back(std::make_pair(101, 13));
v2.push_back(std::make_pair(101, 14));
v2.push_back(std::make_pair(102, 12)); //match
v2.push_back(std::make_pair(103, 1));
v2.push_back(std::make_pair(103, 10));
v2.push_back(std::make_pair(103, 12)); // match
v2.push_back(std::make_pair(103, 15));
auto intersection = _intersect_two_words(v1, v2);
for (auto entry : intersection)
{
std::cout << entry.first << ", " << entry.second << "+" << (entry.second + 1) << std::endl;
}
return 0;
}
Canlı örnek: http://ideone.com/XRfhAI
değil ne tam olarak soruyorsunuz emin - "A numarası içeren belgelerinizin olduğunu belirlemek için nasıl soruyorsunuz biri philips tornavida "veya hangi belgeler" A "," sayı "" bir "," philips "veya" tornavida "sözcüklerini içerir. Eğer birincisi, ardışık olmak zorunda mı yoksa "Bir tornavida üzerindeki tutamakların sayısı her ikisi de philips ve pozidrive için bir tanesi" olacak mı? –
@MatsPetersson, ardışık olması gerekiyor. –
İlgili: http://stackoverflow.com/questions/2659120/how-to-search-phrase-queries-in-inverted-index-structure – jogojapan