【问题标题】:sorting two dimensional array... exception occurred (C++)对二维数组进行排序...发生异常 (C++)
【发布时间】:2021-07-27 06:14:27
【问题描述】:

在解决问题时,需要对二维数组进行排序。我使用了归并排序,并设置了

#include <iostream>
#include <stack>
#include <queue>
#include <vector>

using namespace std;
int*sorted[1000]; 
void merge(int** list, int left, int mid, int right); 
void merge_sort(int** list, int left, int right);
int main(void) {
    int N;
    vector <int> L, H; 
    int l, h, max = 0, max_position, highest, highest_position = 0, area = 0;   cin >> N;
    int** info = (int**)malloc(sizeof(int*) * N); 

    for (int i = 0; i < N; i++) {
        info[i] = (int*)malloc(sizeof(int) * 2); 
        }
    }
    merge_sort(info, 0, N - 1); 


}
void merge(int** list, int left, int mid, int right) {
    int i, j, k, l; 
    i = left; j = mid + 1; k = left; 

    for (int s = 0; s < 7; s++) {
        for (int v = 0; v < 2; v++) {
            cout << list[s][v] << ' ';
        }
        cout << '\n'; 
    }


    while (i <= mid && j <= right) {
        if (list[i][1] <= list[j][1])   // exception occured 
        {
            sorted[k++] = list[i++]; 
        }
        else { 
            sorted[k++] = list[j++];
        }
    }
    if (i > mid) // 1번째 array를 다 쓴 경우 
    {
        for (l = j; l <= right; l++) {
            sorted[k++] = list[l];
        }
    }
    else {
        for (l = i; l <= mid; l++) {
            sorted[k++] = list[l]; 
        }
    }
    for (l = left; l <= right; l++) {
        list[l] = sorted[k]; //  I think problem is related with this line 
    }

}
void merge_sort(int** list, int left, int right) {
    int mid; 
    if (left < right) {
        mid = (left + right) / 2;
        merge_sort(list, left, mid);
        merge_sort(list, mid + 1, right);
        merge(list, left, mid, right); 
    }
}

我分配了排序时需要的排序数组作为整数指针数组,因为我认为我需要分配二维数组每一行的收件人。

但问题似乎表明我与指针有关的基本想法是错误的。有人可以帮我解决这个问题吗?

【问题讨论】:

  • int** info = (int**)malloc(sizeof(int*) * N); -- info[i] = (int*)malloc(sizeof(int) * 2); -- 你为什么不在这里使用std::vector?如果你这样做了,你可能有机会找出问题所在,因为vector 有一个检查数组边界的at() 函数。
  • 我在这里看不到任何套装! malloc 应该创建一个吗?也许你需要标准集?

标签: c++ sorting


【解决方案1】:

在您的情况下,它实际上并不是对二维数组进行排序,而只是对整数对进行排序。 您可以通过第二个元素来比较它们。另一件事,在这种情况下,您真的不想使用 malloc 或 new 。所以,让我们来看看你的解决方案,慢慢改进它。

  1. 删除不必要的 malloc。

malloc 是一个剩余的 C 函数,(几乎)不应该在 C++ 代码中使用。在 C++ 中,您有 new 做类似的事情,但您也不应该这样做!只需使用std::vector,它会在后台分配,负责内存管理并为您释放它。 (注意,你忘了自己释放内存)。

// in main:
std::vector<std::vector<int>> info;
// set the first dimension, how many "rows" you need
info.resize(N);
// for each "row" change "column" size to 2
for (std::vector<int>& v : info) v.resize(2);

记住,通过引用传递向量以避免复制!

  1. std::pair/struct替换第二维

如果您总是知道其中一个维度,很可能您只是在对数字对/元组或一些有意义的“对象”进行排序。

所以你把上面的代码替换为:

// in main:
std::vector<std::pair<int, int>> info;
// only one dimension, how many pairs of ints this vector holds
info.resize(N);

如果这些是代表某物的数字,例如一本书的 ID 和年龄,您可以将它们保存在一个结构中。

// below includes, in global scope:

struct BookInfo {
  int age;
  int id;
};

// in main
std::vector<BookInfo> info;
// only one dimension, how many book infos this vector holds
info.resize(N);
  1. 使用标准库!

在标准库中,您有一个 std::sort 函数。它可以作为一个参数,你想如何比较元素 - 在你的情况下,通过对的第二个值。

因此,您可以通过首先创建一个比较两个元素的函数来对所有内容进行排序:

bool compareBookInfos(const BookInfo& b1, const BookInfo& b2) {
  // return true, if b1 should be before b2 in sorted array
  return b1.id < b2.id;
}

或对相同:

bool compareIntPairBy2nd(const std::pair<int, int>& p1, const std::pair<int, int>& p2) {
  // return true, if p1 should be before p2 in sorted array
  return p1.second < p2.second;
}

现在,调用std::sort 方法:

  std::sort(info.begin(), info.end(), compareBookInfos);

几行代码就搞定了!

如果是编写自己的排序函数的任务,std::vector of pairs/structs 仍应改进您的代码并帮助您调试问题,可能提供更好的诊断。

【讨论】:

  • 对于任何更有经验的读者 - 您可以使用 std::vector 构造函数而不是调整它的大小,我只是想详细一点以确保代码对于初学者来说是可以理解的。
  • 比较函数可以用 lambda 代替 - 和以前一样,不想在答案中放太多东西。
  • 非常感谢您的善意解释。我在学校学习了 C,几乎是 C++ 的初学者,所以我在 C++ 语言中误用了 malloc 函数。但我仍然想知道为什么我的第一个代码出错了。能简单给我解释一下吗?
  • 您标记为您认为错误的那一行,确实是错误的。然而,这不是唯一的问题。让我们看一下代码,逐步改进(暂时忽略 2D malloc)。 1. 如果你对超过 1000 个数字进行排序,程序会崩溃,导致你的“排序”缓冲区太小,修复:godbolt.org/z/hch9vGcGv 2. 如果变量有意义的话,应该在声明时初始化,并且只在需要时声明,而不是在函数顶部,修复:godbolt.org/z/njbGdaavP(这两个现在只是装饰性的,更多在下面的 cmets 中)
  • 3.检查代码很奇怪,因为它总是显示数组的 7 个第一个元素(如果少则崩溃(,让我们删除它。4. 正确修复 - 是的,你认为错误的行确实是错误的 - 在合并排序中, 您将数据放在缓冲区中的相同位置,它们应该在原始缓冲区中。相反,请注意 - 您总是复制相同的值(可能超出数组范围)。修复:godbolt.org/z/fGhvYqx4b 5. 更多外观修复 - if-else 是不必要的,在 for 循环中已经处理了相同的条件,修复:godbolt.org/z/zEz6KEqEe
猜你喜欢
  • 2013-08-17
  • 2011-02-17
  • 2019-05-17
  • 2015-01-30
  • 2012-12-15
  • 2018-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多