首页 > 解决方案 > 不明白如何使用 or,and,not 进行搜索查询

问题描述

我正在重新发布这个问题,因为我现在修复了它,以便更容易准确地理解我需要做什么。

我声明了一个函数:

set<string> findQueryMatches(map<string, set<string>>& index, string sentence);

该映射是一个已经填充了键和值的映射,而字符串将是一个看起来像“fish +red”的句子。地图的键和值来自我在之前的函数中读取的文件,示例如下:

www.shoppinglist.com
EGGS! milk, fish,      @  bread cheese
www.rainbow.org
red ~green~ orange yellow blue indigo violet
www.dr.seuss.net
One Fish Two Fish Red fish Blue fish !!!
www.bigbadwolf.com
I'm not trying to eat you

网站名称是值,而单独的单词(也有一个清除标点符号的 clean token 功能,所以 egg! 变成 egg 并且所有奇怪的符号都被删除)是地图的键。因此,如果您搜索 fish,您将获得该关键字的值列表。

在上面的函数 SearchQueryMatches 中,我输入了一个字符串句子,它必须将术语作为复合查询来处理,其中单个术语被合成为一个组合结果。

输入的字符串将包含空格、+ 和 -。减号表示结果必须匹配一个术语而不匹配另一个,加号表示结果必须匹配两个项目,而没有任何前言的空格表示它们是联合的,因此它们匹配一个或另一个。

例如,

“tasty -mushrooms simple +cheap”翻译成“没有蘑菇的美味或简单又便宜”

我从做分隔句子的字符串流开始,然后做了 if 语句,如

if (word[0] == '+').....

在我将这些词分开并知道如何处理它们之后,我还必须再次调用我的助手清理函数以在开始搜索之前从 + 和 - 中清理它们。

但是现在,我正在为接下来需要做的事情而苦苦挣扎。我从 C++ 集合库中听说过 set_intersection 函数,但我从未使用过它们,而且老实说,对于如何使用它完全没有想法。

返回将是一组满足搜索查询的网站。

什么是对 if 语句内部进行编程的好方法,每次有 +、- 或没有前言时它们会做什么?我完全迷失了这一点。

标签: c++data-structuressearchqueryset

解决方案


当然,您可以使用 set_intersection、set_difference 和 set_union 来解决问题。这是一个关于如何在您的问题中使用这些功能的示例:

std::set<std::string> findQueryMatches(std::map<std::string, 
    std::set<std::string>>& index, std::string sentence) {
    std::set<std::string> url_set;
    std::stringstream ss;
    std::string str;
    ss.str(sentence);
    while(ss >> str) {
        if(str[0] == '-') { //difference
            std::set<std::string> difference_data;
            std::set_difference(url_set.begin(), url_set.end(), index[str.substr(1, str.size() - 1)].begin(), index[str.substr(1, str.size() - 1)].end(), 
                 std::inserter(difference_data, difference_data.begin()));
            url_set = difference_data;
            std::cout<<str<<": ";
            for(auto const& x: url_set) {
                std::cout<<x<<' ';
            }
            std::cout<<'\n';
        } else if(str[0] == '+') { //intersection
            std::set<std::string> intersection_data;
            std::set_intersection(index[str.substr(1, str.size() - 1)].begin(), index[str.substr(1, str.size() - 1)].end(), url_set.begin(), url_set.end(),
                 std::inserter(intersection_data, intersection_data.begin()));
            url_set = intersection_data;
            std::cout<<str<<": ";
            for(auto const& x: url_set) {
                std::cout<<x<<' ';
            }
            std::cout<<'\n';
        } else { //union
            std::set<std::string> union_data;
            std::set_union(index[str].begin(), index[str].end(), url_set.begin(), url_set.end(),
                 std::inserter(union_data, union_data.begin()));
            url_set = union_data;
            std::cout<<str<<": ";
            for(auto const& x: url_set) {
                std::cout<<x<<' ';
            }
            std::cout<<'\n';
        }
    }
    return url_set;
}

请记住,您必须为 set_intersection、set_difference 和 set_union 提供一个输出运算符(看看这个:https ://en.cppreference.com/w/cpp/algorithm/set_difference或者这个如何找到两个 std 的交集: :在 C++ 中设置?)。这些输出运算符可以这样定义:

template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator std::set_union ( InputIterator1 first1, InputIterator1 last1,
                                  InputIterator2 first2, InputIterator2 last2,
                                  OutputIterator result );
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator std::set_intersection ( InputIterator1 first1, InputIterator1 last1,
                                  InputIterator2 first2, InputIterator2 last2,
                                  OutputIterator result );      
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator std::set_difference ( InputIterator1 first1, InputIterator1 last1,
                                  InputIterator2 first2, InputIterator2 last2,
                                  OutputIterator result );  

例如给定这个数据:

www.shoppinglist.com
EGGS! milk, fish      @  bread cheese
www.rainbow.org
red ~green~ orange yellow blue indigo violet
www.dr.seuss.net
One Fish Two Fish Red fish Blue fish !!!
www.bigbadwolf.com
I'm not trying to eat you milk,

还有这句话:

milk, +milk, Blue +fish -Fish

结果是:

milk,: www.bigbadwolf.com www.shoppinglist.com
+milk,: www.bigbadwolf.com www.shoppinglist.com
Blue: www.bigbadwolf.com www.dr.seuss.net www.shoppinglist.com
+fish: www.dr.seuss.net www.shoppinglist.com
-Fish: www.shoppinglist.com

干杯!


推荐阅读