STL 컨테이너에서 하위 의한 요소를 제거하는 방법 (객체 다른 필드 사이 용어 문자열을 문자열 필드 contai 용어 노드) 어떤 처리 후의I 객체의 벡터가
class TermNode {
private:
std::wstring term;
double weight;
...
public:
...
};
상기 산출 같은
std::vector<TermNode *> termlist;
이 벡터의 결과 목록 점수가 이러한 개체가 마지막으로 TermNode 포인터의 벡터에 저장된 얻을, 400 개의 항목을 포함하는 다음과 같습니다
DEBUG: 'knowledge' term weight=13.5921
DEBUG: 'discovery' term weight=12.3437
DEBUG: 'applications' term weight=11.9476
DEBUG: 'process' term weight=11.4553
DEBUG: 'knowledge discovery' term weight=11.4509
DEBUG: 'information' term weight=10.952
DEBUG: 'techniques' term weight=10.4139
DEBUG: 'web' term weight=10.3733
...
제가하려는 것은 하위 문자열에 대한 최종 목록도 용어 목록 안의 구에 포함되어 있습니다. 예를 들어 위의 목록 조각을 보면 '지식 검색'이라는 문구가 있으므로 '지식''지식' 및 '검색'을 목록에서 제외하고 싶습니다. 이러한 맥락에서 중복된다. 나는 한 마디가 들어있는 구절을 지키고 싶다. 나는 또한 모든 문자열을 같거나 3 자 이하로 제거하려고 생각하고있다. 그러나 그것은 지금 당장의 생각입니다.
이 정리 과정에서는 remove_if/find_if (새로운 C++ lambdas 사용)를 사용하여 클래스를 코딩하고 있으며 해당 클래스를 컴팩트 클래스로 사용하는 것이 좋습니다.
이 문제를 해결하는 방법에 대해서는 잘 모르겠습니다. 문제는 먼저 플래그를 삭제 마커로 설정하여 제거 할 문자열을 먼저 식별해야한다는 것입니다. 그 목록을 사전 처리해야한다는 뜻입니다. 나는 그 단일 용어 중 하나를 포함하고있는 단일 용어와 구문을 찾아야 할 것입니다. 나는 이것이 쉬운 일이 아니며 진보 된 알고리즘이 필요하다고 생각한다. 접미어 트리를 사용하여 하위 문자열을 식별합니까?
벡터에있는 또 다른 루프와 동일한 벡터의 복사본을 정리할 수 있습니다. 나는 가장 효율적인 방법을 찾고있다.
나는 std::list erase incompatible iterator에 나와있는 것과 같은 아이디어 나 방향을 가지고 놀고 있는데, 이는 remove_if/find_if와 Erasing multiple objects from a std::vector?에서 사용 된 아이디어를 사용하고 있습니다.
그래서 기본적으로이 작업을 수행하고 다중 루프를 피하는 스마트 한 방법이 있으며 삭제에 대한 단일 용어를 어떻게 식별 할 수 있습니까? 어쩌면 나는 정말로 뭔가를 놓치고 있을지 모르지만 아마 누군가가 나와서 좋은 힌트를 줄 것입니다.
의견을 보내 주셔서 감사합니다.
/**
* Functor gets the term of each TermNode object, looks if term string
* contains spaces (ie. term is a phrase), splits phrase by spaces and finally
* stores thes term tokens into a set. Only term higher than a score of
* 'skipAtWeight" are taken tinto account.
*/
struct findPhrasesAndSplitIntoTokens {
private:
set<wstring> tokens;
double skipAtWeight;
public:
findPhrasesAndSplitIntoTokens(const double skipAtWeight)
: skipAtWeight(skipAtWeight) {
}
/**
* Implements operator()
*/
void operator()(const TermNode * tn) {
// --- skip all terms lower skipAtWeight
if (tn->getWeight() < skipAtWeight)
return;
// --- get term
wstring term = tn->getTerm();
// --- iterate over term, check for spaces (if this term is a phrase)
for (unsigned int i = 0; i < term.length(); i++) {
if (isspace(term.at(i))) {
if (0) {
wcout << "input term=" << term << endl;
}
// --- simply tokenze term by space and store tokens into
// --- the tokens set
// --- TODO: check if this really is UTF-8 aware, esp. for
// --- strings containing umlauts, etc !!
wistringstream iss(term);
copy(istream_iterator<wstring,
wchar_t, std::char_traits<wchar_t> >(iss),
istream_iterator<wstring,
wchar_t, std::char_traits<wchar_t> >(),
inserter(tokens, tokens.begin()));
if (0) {
wcout << "size of token set=" << tokens.size() << endl;
for_each(tokens.begin(), tokens.end(), printSingleToken());
}
}
}
}
/**
* return set of extracted tokens
*/
set<wstring> getTokens() const {
return tokens;
}
};
/**
* Functor to find terms in tokens set
*/
class removeTermIfInPhraseTokensSet {
private:
set<wstring> tokens;
public:
removeTermIfInPhraseTokensSet(const set<wstring>& termTokens)
: tokens(termTokens) {
}
/**
* Implements operator()
*/
bool operator()(const TermNode * tn) const {
if (tokens.find(tn->getTerm()) != tokens.end()) {
return true;
}
return false;
}
};
...
findPhrasesAndSplitIntoTokens objPhraseTokens(6.5);
objPhraseTokens = std::for_each(
termList.begin(), termList.end(), objPhraseTokens);
set<wstring> tokens = objPhraseTokens.getTokens();
wcout << "size of tokens set=" << tokens.size() << endl;
for_each(tokens.begin(), tokens.end(), printSingleToken());
// --- remove all extracted single tokens from the final terms list
// --- of similar search terms
removeTermIfInPhraseTokensSet removeTermIfFound(tokens);
termList.erase(
remove_if(
termList.begin(), termList.end(), removeTermIfFound),
termList.end()
);
for (vector<TermNode *>::const_iterator tl_iter = termList.begin();
tl_iter != termList.end(); tl_iter++) {
wcout << "DEBUG: '" << (*tl_iter)->getTerm() << "' term weight=" << (*tl_iter)->getNormalizedWeight() << endl;
if ((*tl_iter)->getNormalizedWeight() <= 6.5) break;
}
...
내가 때문에 내 우분투에서 C++ 11 람다 구문을 사용 could'nt 다음과 같이
업데이트
나는 방식 Scrubbins 권장 중복 단일 용어의 제거를 구현 서버에는 현재 g ++ 4.4.1이 설치되어 있습니다. 어쨌든. 그것은 지금 당장 일을합니다. 갈 길이는 가중치가있는 용어의 품질을 다른 검색 결과 세트로 확인하고 품질을 향상시킬 수있는 방법과 원래의 검색어와 함께 관련성이 높은 용어를 늘릴 수있는 방법을 찾는 것입니다. 할 수있는 일이 쉽지 않을 수도 있습니다. "단순한 경험적 방법"이 있기를 바랍니다. 그러나 조금 더 자세히 살펴보면 또 다른 새로운 질문이 될 수 있습니다. :-)
이렇게 많은 의견을 보내 주셔서 감사합니다.
제목과 같이 보입니다. 약간의 오해의 소지가 있습니다. 이것은 벡터 문제가 아니며, 이것은 텍스트 처리 문제입니다. 하위 문자열을 식별하면 벡터에서 벡터를 제거하는 것은 특히 400 개의 항목 만있는 경우에 특히 간단합니다. – Rook
TermNode 객체에 대한 스마트 포인터의'vector'를 사용하지 않는 이유는 무엇입니까? 그렇게하면,'find' 연산 후에 반환 된 포인터를'삭제 '하는 것을 줄일 수 있습니다. – dirkgently
저는 용어 길이의 역순으로 벡터를 정렬하려고합니다. 벡터를 반복하고 각 단어를 개별 단어로 분리하여 단어를'std :: set '에 놓습니다. 단어가 이미 세트에 존재하면 삭제할 필요가 있다고 플래그를 지정한 다음 벡터 제거에 대해 걱정하십시오. – Rook