将数组拆分成不同深度的对

时间:2017-07-03 23:10:43

标签: c++ arrays algorithm recursion optimization

让我们有一个数组a[0],a[1],..,a[6]。我想实现一种能够返回各种深度的算法。为了使其更容易理解,请考虑我必须为不同的深度值

返回算法
depth: 1, 
return: 
       (a[6] - a[0]); /*the only possible case for depth = 1*/

depth: 2, 
return: 
       (a[1] - a[0]) + (a[6] - a[2]); /*first case*/
       (a[2] - a[0]) + (a[6] - a[3]); /*second case*/
       (a[3] - a[0]) + (a[6] - a[4]); /*third case*/
       (a[4] - a[0]) + (a[6] - a[5]); /*fourth*/

depth: 3,
return:
       (a[1] - a[0]) + (a[3] - a[2]) + (a[6] - a[4]); /*first case*/
       (a[1] - a[0]) + (a[4] - a[2]) + (a[6] - a[5]); /*second case*/
       (a[2] - a[0]) + (a[4] - a[3]) + (a[6] - a[5]); /*third case*/

这是长度为7的数组的示例。我希望算法适用于任意长度的数组。

我能够使用递归实现算法。以下是C ++中的代码

int arr[101]; /*Original array with length N = 100*/
set <__int64> Partitions; /*Set, for accumulation of the sum of the partitions*/

void get_partitions(int start, int end, int depth, int sum) {
    if (depth == 1) {
        sum += (arr[end] - arr[start]);

        Partitions.insert(sum);
    }
    else {
        int k = end - 2 * (depth - 1);
        int new_start = start + 1;

        while (new_start <= k) {
            int current_sum = (arr[new_start] - arr[new_start - 1]);

            get_partitions((new_start + 1), end, (depth - 1), (sum + current_sum));

            new_start++;
        }
    }
}

int main() {
    get_partitions(0, 100, 5, 0);

    //processing of Partitions

    return 0;
}

此实现存在工作问题。对于大维数组,程序执行时间太长。

是否可以改进算法?这个算法还有其他任何实现吗?我很感激你的答案。

1 个答案:

答案 0 :(得分:0)

您可以使用以下内容:

std::vector<std::size_t> initialize(std::size_t depth)
{
    std::vector<std::size_t> res(depth - 1);

    int i = 1;
    for (auto& e : res) {
        e = i;
        i += 2;
    }
    return res;
}

bool increase(std::vector<std::size_t>& indexes, std::size_t max)
{
    auto m = max;
    auto rit = indexes.rbegin();
    for (; rit != indexes.rend(); ++rit) {
        ++*rit;
        if (*rit + 1 != m) {
            m = *rit;
            for (auto it = rit.base(); it != indexes.end(); ++it) {
                *it = m + 2;
                m += 2;
            }
            if (m < max) {
                return true;
            }
        }
        m = *rit - 1;
    }
    return false;
}

Demo