在C ++中找到两个具有相等和的集合的快速方法是什么?

时间:2017-02-17 03:46:47

标签: c++ performance dynamic-programming multimap

我需要一种有效的方法来查看ints的集合列表,以查看任何两个集合具有相同的总和。具体来说,在这种情况下,我正在生成作为参数给出的int列表的powerset。从那个powerset,我需要找到一对总和为相同值的子集。

目前,我正在尝试使用动态编程方法(下面的解释):

typedef std::vector<int> intvec;
typedef std::vector<std::vector<int> > intvecvec;
typedef std::multimap<int,int> intmap;

/* Functions previously shown here that were removed:
 * intvecvec search_for_sum(intvec num_list)
 * and
 * int sum_exists(std::vector<intvec> pset, int index, intmap &sums)
 */

/* This function was previously just called powerset(), and wasn't
 * shown because the problem wasn't happening here. After refactoring,
 * I removed the functions that were shown here previously and simply
 * iteratively checked for sum matches while generating the powerset
 */
intvecvec powerset_search(intvec num_list)
{
    intvecvec result;
    std::multimap<int, intvec> power_set;
    for (int c = 0; c < pow(2, num_list.size()); c++) {
        intvec temp;
        for (int i = 0; i < num_list.size(); i++) {
            if (c & (1 << i)) {
                temp.push_back(num_list.at(i));
            }
        }
        int sum = std::accumulate( temp.begin(), temp.end(), 0 );
        std::multimap<int, intvec>::iterator it = power_set.find(sum);
        if (it == power_set.end()) {
            power_set.insert(std::make_pair(sum, temp));
        } else {
            result.push_back(it->second);
            result.push_back(temp);
            break;
        }
    }
    return result;
}

search_for_sum()创建给定ints列表的powerset,以及multimap所谓的sums。对于powerset中的每个元素,计算其总和。如果尚未遇到该总和,则将总和和当前索引插入sums。否则,返回当前集和已插入sums的集。

这很有效。问题是,对于大型num_list,如果有一个解决方案,可能需要几分钟才能找到解决方案。这比仅执行双for - 循环并且每次计算总和以查找匹配的强力方法要慢得多。我有更好的方法吗?

<小时/>

编辑:所以我能够通过将总和检查步骤移动到实际生成powerset的时间来解决这个问题,迭代检查所有先前输入的总和并在找到匹配时返回。但是,正如评论中所要求的那样,我还要重新解决问题描述(希望)删除最初存在的模糊性。

1 个答案:

答案 0 :(得分:0)

我能够通过将总和检查步骤移动到实际生成powerset的时间来解决这个问题,迭代检查所有先前输入的总和并在找到匹配时返回。