【发布时间】:2020-05-02 16:05:07
【问题描述】:
我正在尝试创建一个程序来计算一对点之间的最小距离,但我不知道如何使我的代码工作。它有时似乎适用于某些 n 输入,但并非始终如一。在尝试解决此问题时,我遇到了堆损坏错误、错误的数组新长度以及最近的严重错误 c0000374。我猜这是非常愚蠢的事情,但我无法提出解决方案。
代码基于: https://www.geeksforgeeks.org/closest-pair-of-points-onlogn-implementation/
#include <iostream>
#include <random>
#include <stdlib.h>
#include <math.h>
#include <algorithm>
#define MAX 1;
struct Point {
float x;
float y;
Point()
{
this->x = 0;
this->y = 0;
}
Point(float x, float y) {
this->x = x;
this->y = y;
}
Point *operator=(const Point *other)
{
this->x = other->x;
this->y = other->y;
return this;
}
};
void merge(Point* &arr, int l, int m, int r) {
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;
Point *L = new Point[n1];
Point *R = new Point[n2];
for (i = 0; i < n1; i++) {
L[i] = &arr[l + i];
}
for (j = 0; j < n2; j++) {
R[j] = &arr[m + 1 + j];
}
i = 0;
j = 0;
k = l;
while (i < n1 && j < n2)
{
if (L[i].x <= R[j].x)
{
arr[k] = L[i];
i++;
}
else
{
arr[k] = R[j];
j++;
}
k++;
}
while (i < n1)
{
arr[k] = L[i];
i++;
k++;
}
while (j < n2)
{
arr[k] = R[j];
j++;
k++;
}
}
void mergeSort(Point* &arr, int l, int r)
{
if (l < r)
{
int m = l + (r - l) / 2;
mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);
merge(arr, l, m, r);
}
}
int compareX(Point a, Point b) {
return ((float)a.x >= (float)b.x) ? 1 : -1;
};
float dist(Point p1, Point p2)
{
return sqrt((p1.x - p2.x)*(p1.x - p2.x) +
(p1.y - p2.y)*(p1.y - p2.y)
);
}
float stripClosest(Point* &strip, int size, float d)
{
float min = d;
for (int i = 0; i < size; ++i)
for (int j = i + 1; j < size && (strip[j].y - strip[i].y) < min; ++j)
if (dist(strip[i], strip[j]) < min)
min = dist(strip[i], strip[j]);
return min;
}
float min(float x, float y)
{
return (x < y) ? x : y;
}
float bruteForce(Point P[], int n)
{
float min = MAX;
for (int i = 0; i < n; ++i)
for (int j = i + 1; j < n; ++j)
if (dist(P[i], P[j]) < min)
min = dist(P[i], P[j]);
return min;
}
float closestUtil(Point P[], Point Pi[], int n)
{
if (n <= 3)
{
return bruteForce(P, n);
}
else
{
int mid = n / 2;
Point midPoint = P[mid];
int li = 0, ri = 0;
Point* Pyl = new Point[mid+1];
Point* Pyr = new Point[n - (mid -1)];
Point* strip = new Point[n];
for (int i = 0; i < n; i++)
{
if (P[i].y <= midPoint.y)
Pyl[li++] = Pi[i];
else
Pyr[ri++] = Pi[i];
}
float dl = closestUtil(P, Pyl, mid);
float dr = closestUtil(P + mid, Pyr, n - mid);
float d = min(dl, dr);
int j = 0;
for (int i = 0; i < n; i++)
if (abs(P[i].y - midPoint.y) < d)
strip[j] = Pi[i], j++;
return min(d, stripClosest(strip, j, d));
}
}
int main() {
int n;
std::cout << "Input the amount of points" << std::endl;
std::cin >> n;
Point* arr = new Point[n];
std::default_random_engine generator;
std::uniform_real_distribution<float> distribution(0.0, 1.0);
for (int i = 0; i < n; i++)
{
float xi = distribution(generator);
float yi = distribution(generator);
arr[i].x = xi;
arr[i].y = yi;
}
mergeSort(arr, 0, n - 1);
for (int i = 0; i < n; i++)
std::cout << arr[i].x << std::endl;
std::cout << bruteForce(arr, n) << std::endl;
std::cout << closestUtil(arr, arr, n);
return 0;
}
【问题讨论】:
-
你为什么要用这么多指针?
-
首先,将
Point *operator=(const Point *other)更改为Point &operator=(const Point &other)并在其末尾返回*this。 -
Formerlyknownas_463035818 对此并没有很好的答案,在过去的几个小时里,我一直在尝试几乎所有想到的东西,这是我代码的最新状态。 @goodvibration 改变了它,除了 n=5 或 n=15 之类的某些情况外仍然不起作用
-
这是很多有很多问题的代码,其中很多与不使用
std::vector有关 -
在编程时,您需要学习将问题拆分成更小的块。整个代码太多了,无法一口气完成。专注于单独的部分,编写测试,只有当你知道你已经拥有的代码可以正常工作时才继续。
标签: c++ pointers memory dynamic