【问题标题】:Modify c++ code that finds the subarray with the maximum sub less than or equal to given sum修改找到最大 sub 小于或等于给定 sum 的子数组的 c++ 代码
【发布时间】:2021-04-25 22:30:14
【问题描述】:

我想修改一个函数,该函数负责将子数组(在本例中为向量)写入控制台,其中最高和小于或等于给定和。我想改变的是函数在计算总和时应该能够多次使用同一个元素。

例如:如果给定的向量是{30, 60},而所需的总和是135,它现在会写出60, 30,但我想做的是写60, 6060, 30, 3030, 30, 30, 30 以任意顺序排列,因为给定向量中的元素在计算总和时应该是可重用的。

这是当前形式的函数:

void findMaxSubarraySum(std::vector<int> arr, int sum)
{
    int curr_sum = arr[0], max_sum = 0, start = 0;
    std::vector<int> maxArr, currArr;

    currArr.push_back(arr[0]);

    for (int i = 1; i < arr.size(); i++) {

        if (max_sum <= curr_sum) {
            max_sum = curr_sum;
            maxArr = currArr;
        }

        while (curr_sum + arr[i] > sum && start < i) {
            curr_sum -= arr[start];
            currArr.erase(std::remove(currArr.begin(), currArr.end(), arr[start]), currArr.end());
            start++;
        }

        curr_sum += arr[i];
        currArr.push_back(arr[i]);
    }

    if (curr_sum <= sum) {
        max_sum = curr_sum;
        maxArr = currArr;
    }

    for (int element : maxArr) {
        std::cout << element << ", ";
    }
}

我尝试通过将以下代码添加到函数的开头将向量的每个元素添加到自身 sum / element 次:

for (int element : arr) {
    int n = sum / element;
    for (int i = 1; i < n; ++i) {
        arr.push_back(element);
    }
}

但是这样做的问题是它不仅效率很低,而且也不起作用,因为程序只是退出而没有输出任何东西。

我怎样才能修改这个功能(或者只写一个不同的工作方式)来做到这一点?

【问题讨论】:

  • 在编写一行代码之前,您应该先在纸上解决这个问题。然后,一旦你解决了这个问题,然后编写适合你所写内容的程序。仔细考虑已经编写的显然效率低下或“不起作用”的代码不会有帮助。
  • @PaulMcKenzie 好吧,我试过了,但到目前为止,我以前的计划都没有真正奏效,这是我得到的最接近的计划。我最初的想法是尝试递归,但我不知道如何检查我得到的是否比以前的数组大,因为我所做的是经历所有可能性,并且每次检查可能性的第一个元素被更改一个新的递归行开始了,我不知道如何检查这里的最终结果是否比上一个递归行更好。
  • 第一步是弄清楚如何描述问题。您并不是真正要求子数组,而是要求具有替换的数组元素的每个组合,总和最多为 M。 (替换只是意味着您替换每个选择的元素,以便可以重复使用)。
  • 是的,没错,但在我当前的代码中,它是一个子数组,但它并没有真正的区别,因为它的所有元素都是在满足某些条件并且没有停止的情况下手动添加的我添加了一些会改变它的子数组性质的东西。 @无用
  • 您在谈论数据的组织,这是特定于您的代码的。我说的是这些操作的一般名称,因此您可以找到现有的参考资料,而不是试图从头开始重新发明组合数学。

标签: c++ vector sum c++17 sub-array


【解决方案1】:

修改 c++ 代码,找到最大 sub 小于或等于给定 sum 的子数组

不要,从头开始写。试图将一种算法变异为另一种算法是困难的,即使在你完全理解两者的情况下也是如此。由于您听起来不像您了解新的实际应该如何操作,因此这永远不可能奏效。

...将子数组...写入控制台...

忠告:不要将 I/O 混入您的算法。测试和调试只接受输入并返回结果的纯函数要容易得多。

编写一个函数来调用它然后打印结果也很容易。至少,假设您可以返回整个容器。

对于无限大或不切实际的大序列,您确实需要类似 Python 生成器之类的东西,它在 C++ 中编写起来有点困难(但首先做最简单的事情并使用小输入进行测试,您可以担心大如果它成为一个问题,以后再做)。

... 小于或等于给定总和的最高总和。我想改变的是函数在计算总和时应该能够多次使用同一个元素。

第一步是弄清楚如何描述问题。您并不是真正要求子数组,而是要求替换数组元素的每个组合,总和最多为 M。 (替换只是意味着您替换每个选定的元素,以便可以重复使用)。

让我们给这些东西起个名字,让你想生产

长度为 N 的集合中的每个组合 C 使得 sum(C)

您可以阅读这类东西(permutationscombinations 等)通常是如何完成的,但有一个技巧可以在您想要时修剪您的计算限制组合的总和with-replacement

  1. 对输入进行排序,使最大的元素在前
  2. 走过任何大于Max 的东西,因为我们知道我们永远无法使用它
  3. 现在我们在排序向量的某个子集上有一个稍微简单的函数(它可能是全部,但至少我们知道每个元素都是可用的)

最后,您可以开始对输出进行分类。例如,您应该将每个单独的元素作为长度为 1 的序列(因为我们在步骤 2 中过滤掉了任何过大的元素)。如果e*e &lt;= Max,你应该有一个包含两个相同元素的2元素序列,依此类推。您可以先明确地写出每个案例,然后在您了解它们的工作方式时将它们重构为(嵌套)循环。

【讨论】:

    猜你喜欢
    • 2022-10-12
    • 2016-09-30
    • 2021-10-24
    • 1970-01-01
    • 2014-11-01
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    • 2021-06-09
    相关资源
    最近更新 更多