c++ 我无法从这段代码中得到所需的输出来寻找最小绝对差

pnwntuvh  于 2023-05-02  发布在  其他
关注(0)|答案(1)|浏览(178)

到目前为止我写的代码是

#include <iostream>
using namespace std;

void heapify(int arr[], int n, int i) {
    int smallest = i; 
    int l = 2 * i + 1; 
    int r = 2 * i + 2; 

    if (l < n && abs(arr[l] - arr[i]) < abs(arr[smallest] - arr[i]))
        smallest = l;

    if (r < n && abs(arr[r] - arr[i]) < abs(arr[smallest] - arr[i]))
        smallest = r;

    if (smallest != i) {
        swap(arr[i], arr[smallest]);
        heapify(arr, n, smallest);
    }
}

int minAbsoluteDifference(int arr[], int n) {
    for (int i = n / 2 - 1; i >= 0; i--)
        heapify(arr, n, i);

    int minDiff = abs(arr[1] - arr[0]);

    for (int i = 2; i < n; i++) {
        minDiff = min(minDiff, abs(arr[i] - arr[0]));
        heapify(arr, i, 0);
    }

    return minDiff;
}

int main() {
    int n;
    cout << "Enter the size of the array: ";
    cin >> n;
    int arr[n];
    cout << "Enter the elements of the array:\n";
    for (int i = 0; i < n; i++) {
        cin >> arr[i];
    }
    int minDiff = minAbsoluteDifference(arr, n);
    cout << "Minimum absolute difference between any two distinct elements in the array is: " << minDiff << endl;
    return 0;
}

对于测试用例

-5 -3 -1 0 2

输出应该是1,因为-1和0之间的差是最小的i。e 1,但输出为2。我在代码中哪里出错了,任何形式的帮助都将不胜感激。

6rqinv9w

6rqinv9w1#

显然,所呈现的代码对于任务来说太复杂了。
让我们先想想如何解决这个问题。简单的方法是将数组的每个值与其他值进行比较,计算delta,然后取绝对值。其结果将是时间复杂度的二次方,这将花费太长的时间。
因此,第一个设计选择将是对数组中的元素进行排序。然后,在较大的元素之前总是有较小的元素,并且较大元素和较小元素之间的增量总是正的。
排序后,我们可以简单地计算下一个和前一个值之间的增量,并与当前最小值进行比较。如果我们找到一个新的最小值,我们就能记住它。
附加提示:在你的main中,你使用了int arr[n];语句这是一个VLA,一个可变长度的数组,它不是 C++ 的一部分。(有些编译器会忽略它,并编译它)。所以,这是不允许的。您可以简单地使用drop in replacement std::vector,它的另一个优点是知道它的大小。
那么算法很简单:

  • 获取要读取的元素数
  • 读数字
  • 把它们分类
  • 处理1个元素的特殊情况
  • 在循环中,计算下一个元素和前一个元素之间增量
  • 检查delta是否是新的最小值

直接的实现可能看起来像下面这样:

#include <iostream>
#include <vector>
#include <cmath>
#include <limits>
#include <algorithm>

int minAbsoluteDifference(std::vector<int>& v) {
    int minDelta = 0;
    // Sanity check for empty vector
    if (not v.empty()) {

        // Special case for vector with one element
        if (v.size() == 1)

            // Then simply return the first elemnt
            minDelta = std::abs(v[0]);

        else {
            // Vector contains now at least 2 elements
            // First sort
            std::sort(v.begin(), v.end());

            // Initialize minDelta initially to a maximum value
            minDelta = std::numeric_limits<int>::max();

            // Now in a loop, calculate all deltas
            for (std::size_t i = 1; i < v.size(); ++i) {

                // Calculate delta, Will always be positive, because of previous sorting
                const int delta = v[i] - v[i - 1];

                // Check for a new ninimum delta
                if (delta < minDelta)
                    // And, if found, remeber new nin delta
                    minDelta = delta;
            }
        }
    }
    return minDelta;
}
int main() {
    std::cout << "\nEnter the size of the array: ";

    // Get input from the user and check that
    int numberOfElements = 0;
    if ((std::cin >> numberOfElements) and (numberOfElements > 0)) {

        // Create a vector to hold the data
        std::vector<int> arr(numberOfElements);

        std:: cout << "\n\nEnter the elements of the array:\n";
        // Read all values in a loop
        for (int i = 0; i < numberOfElements; ++i) {

            // Read values and check, if it worked
            if (not (std::cin >> arr[i])) {
                std::cout << "\nError: Invalid input\n\n";
                break;
            }
        }

        // If we have valid input, then call function to give the result
        if (std::cin)
            std::cout << "\n\nMinimum absolute difference between any two distinct elements in the array is: " <<
            minAbsoluteDifference(arr) << '\n';
    }
    else
        std::cout << "\nError: Invalid input\n\n";
}

相关问题