C++:候选函数不可行:第一个参数没有从 'Segment [2]' 到 'int *' 的已知转换
C++: candidate function not viable: no known conversion from 'Segment [2]' to 'int *' for 1st argument
这是我正在使用的扫描线算法的 C++ 代码。我正在使用 HeapSort 对点进行排序。但我收到以下 2 个错误:
第 214 行:字符 5:错误:没有匹配函数来调用 'heapSort'
heapSort(arr, n);
第 134 行:字符 6:注意:候选函数不可行:对于第一个参数
,没有已知的从 'Segment [2]' 到 'int *' 的转换
void heapSort(int arr[], int n)
产生了 1 个错误。
我不是很清楚它抛出 2 个错误的原因。
// Implementation of Sweep Line Algorithm
#include <bits/stdc++.h>
using namespace std;
// A point in 2D plane
struct Point
{
int x, y;
};
// A line segment with left as Point
// with smaller x value and right with
// larger x value.
struct Segment
{
Point left, right;
};
// An event for sweep line algorithm
// An event has a point, the position
// of point (whether left or right) and
// index of point in the original input
// array of segments.
struct Event {
int x, y;
bool isLeft;
int index;
Event(int x, int y, bool l, int i) : x(x), y(y), isLeft(l), index(i) {}
// This is for maintaining the order in set.
bool operator<(const Event& e) const {
return y < e.y;
}
};
// Given three colinear points p, q, r, the function checks if
// point q lies on line segment 'pr'
bool onSegment(Point p, Point q, Point r)
{
if (q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) &&
q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y))
return true;
return false;
}
// To find orientation of ordered triplet (p, q, r).
// The function returns following values
// 0 --> p, q and r are colinear
// 1 --> Clockwise
// 2 --> Counterclockwise
int orientation(Point p, Point q, Point r)
{
// See https://www.geeksforgeeks.org/orientation-3-ordered-points/
// for details of below formula.
int val = (q.y - p.y) * (r.x - q.x) -
(q.x - p.x) * (r.y - q.y);
if (val == 0) return 0; // colinear
return (val > 0)? 1: 2; // clock or counterclock wise
}
// The main function that returns true if line segment 'p1q1'
// and 'p2q2' intersect.
bool doIntersect(Segment s1, Segment s2)
{
Point p1 = s1.left, q1 = s1.right, p2 = s2.left, q2 = s2.right;
// Find the four orientations needed for general and
// special cases
int o1 = orientation(p1, q1, p2);
int o2 = orientation(p1, q1, q2);
int o3 = orientation(p2, q2, p1);
int o4 = orientation(p2, q2, q1);
// General case
if (o1 != o2 && o3 != o4)
return true;
// Special Cases
// p1, q1 and p2 are colinear and p2 lies on segment p1q1
if (o1 == 0 && onSegment(p1, p2, q1)) return true;
// p1, q1 and q2 are colinear and q2 lies on segment p1q1
if (o2 == 0 && onSegment(p1, q2, q1)) return true;
// p2, q2 and p1 are colinear and p1 lies on segment p2q2
if (o3 == 0 && onSegment(p2, p1, q2)) return true;
// p2, q2 and q1 are colinear and q1 lies on segment p2q2
if (o4 == 0 && onSegment(p2, q1, q2)) return true;
return false; // Doesn't fall in any of the above cases
}
// Find predecessor of iterator in s.
auto pred(set<Event> &s, set<Event>::iterator it) {
return it == s.begin() ? s.end() : --it;
}
// Find successor of iterator in s.
auto succ(set<Event> &s, set<Event>::iterator it) {
return ++it;
}
void heapify(int arr[], int n, int i)
{
int largest = i; // Initialize largest as root
int l = 2 * i + 1; // left = 2*i + 1
int r = 2 * i + 2; // right = 2*i + 2
// If left child is larger than root
if (l < n && arr[l] > arr[largest])
largest = l;
// If right child is larger than largest so far
if (r < n && arr[r] > arr[largest])
largest = r;
// If largest is not root
if (largest != i) {
swap(arr[i], arr[largest]);
// Recursively heapify the affected sub-tree
heapify(arr, n, largest);
}
}
// main function to do heap sort
void heapSort(int arr[], int n)
{
// Build heap (rearrange array)
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
// One by one extract an element from heap
for (int i = n - 1; i > 0; i--) {
// Move current root to end
swap(arr[0], arr[i]);
// call max heapify on the reduced heap
heapify(arr, i, 0);
}
}
// Returns true if any two lines intersect.
bool isIntersect(Segment arr[], int n)
{
// Pushing all points to a vector of events
vector<Event> e;
for (int i = 0; i < n; ++i) {
e.push_back(Event(arr[i].left.x, arr[i].left.y, true, i));
e.push_back(Event(arr[i].right.x, arr[i].right.y, false, i));
}
// Sorting all events according to x coordinate.
sort(e.begin(), e.end(), [](Event &e1, Event &e2) {return e1.x < e2.x;});
// For storing active segments.
set<Event> s;
// Traversing through sorted points
for (int i=0; i<2*n; i++)
{
Event curr = e[i];
int index = curr.index;
// If current point is left of its segment
if (curr.isLeft)
{
// Get above and below points
auto next = s.lower_bound(curr);
auto prev = pred(s, next);
// Check if current point intersects with
// any of its adjacent
if (next != s.end() && doIntersect(arr[next->index], arr[index]))
return true;
if (prev != s.end() && doIntersect(arr[prev->index], arr[index]))
return true;
// Insert current point (or event)
s.insert(curr);
}
// If current point is right of its segment
else
{
// Find the iterator
auto it = s.find(curr);
// Find above and below points
auto next = succ(s, it);
auto prev = pred(s, it);
// If above and below point intersect
if (next != s.end() && prev != s.end())
if (doIntersect(arr[prev->index], arr[next->index]))
return true;
// Return current point
s.erase(curr);
}
}
return false;
}
// Driver code
int main() {
Segment arr[] = { {{0, 0}, {0, 4}}, {{1, 0}, {5, 0}}};
int n = sizeof(arr)/sizeof(arr[0]);
heapSort(arr, n);
cout << isIntersect(arr, n);
return 0;
}
函数heapSort
声明为
void heapSort(int arr[], int n);
即其第一个参数的类型为int arr[]
,编译器将其调整为int *
.
类型
但是您调用的函数传递的是 Segment[2]
类型的数组作为第一个参数
Segment arr[] = { {{0, 0}, {0, 4}}, {{1, 0}, {5, 0}}};
int n = sizeof(arr)/sizeof(arr[0]);
heapSort(arr, n);
并且没有从类型Segment[2]
(用作函数参数的数组类型arr
)到类型int *
(第一个数组的类型)的隐式转换函数的参数)在编译器将第一个参数 int[]
的类型隐式调整为类型 int *
之后。
解决方案之一是将函数 heapSort
重写为模板函数,例如 like
template <typename T>
void heapSort( T arr[], int n);
在这种情况下,您将需要重写函数 heapSort
也作为模板函数使用的其他函数,
这是我正在使用的扫描线算法的 C++ 代码。我正在使用 HeapSort 对点进行排序。但我收到以下 2 个错误:
第 214 行:字符 5:错误:没有匹配函数来调用 'heapSort'
heapSort(arr, n);
第 134 行:字符 6:注意:候选函数不可行:对于第一个参数
,没有已知的从 'Segment [2]' 到 'int *' 的转换void heapSort(int arr[], int n)
产生了 1 个错误。
我不是很清楚它抛出 2 个错误的原因。
// Implementation of Sweep Line Algorithm
#include <bits/stdc++.h>
using namespace std;
// A point in 2D plane
struct Point
{
int x, y;
};
// A line segment with left as Point
// with smaller x value and right with
// larger x value.
struct Segment
{
Point left, right;
};
// An event for sweep line algorithm
// An event has a point, the position
// of point (whether left or right) and
// index of point in the original input
// array of segments.
struct Event {
int x, y;
bool isLeft;
int index;
Event(int x, int y, bool l, int i) : x(x), y(y), isLeft(l), index(i) {}
// This is for maintaining the order in set.
bool operator<(const Event& e) const {
return y < e.y;
}
};
// Given three colinear points p, q, r, the function checks if
// point q lies on line segment 'pr'
bool onSegment(Point p, Point q, Point r)
{
if (q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) &&
q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y))
return true;
return false;
}
// To find orientation of ordered triplet (p, q, r).
// The function returns following values
// 0 --> p, q and r are colinear
// 1 --> Clockwise
// 2 --> Counterclockwise
int orientation(Point p, Point q, Point r)
{
// See https://www.geeksforgeeks.org/orientation-3-ordered-points/
// for details of below formula.
int val = (q.y - p.y) * (r.x - q.x) -
(q.x - p.x) * (r.y - q.y);
if (val == 0) return 0; // colinear
return (val > 0)? 1: 2; // clock or counterclock wise
}
// The main function that returns true if line segment 'p1q1'
// and 'p2q2' intersect.
bool doIntersect(Segment s1, Segment s2)
{
Point p1 = s1.left, q1 = s1.right, p2 = s2.left, q2 = s2.right;
// Find the four orientations needed for general and
// special cases
int o1 = orientation(p1, q1, p2);
int o2 = orientation(p1, q1, q2);
int o3 = orientation(p2, q2, p1);
int o4 = orientation(p2, q2, q1);
// General case
if (o1 != o2 && o3 != o4)
return true;
// Special Cases
// p1, q1 and p2 are colinear and p2 lies on segment p1q1
if (o1 == 0 && onSegment(p1, p2, q1)) return true;
// p1, q1 and q2 are colinear and q2 lies on segment p1q1
if (o2 == 0 && onSegment(p1, q2, q1)) return true;
// p2, q2 and p1 are colinear and p1 lies on segment p2q2
if (o3 == 0 && onSegment(p2, p1, q2)) return true;
// p2, q2 and q1 are colinear and q1 lies on segment p2q2
if (o4 == 0 && onSegment(p2, q1, q2)) return true;
return false; // Doesn't fall in any of the above cases
}
// Find predecessor of iterator in s.
auto pred(set<Event> &s, set<Event>::iterator it) {
return it == s.begin() ? s.end() : --it;
}
// Find successor of iterator in s.
auto succ(set<Event> &s, set<Event>::iterator it) {
return ++it;
}
void heapify(int arr[], int n, int i)
{
int largest = i; // Initialize largest as root
int l = 2 * i + 1; // left = 2*i + 1
int r = 2 * i + 2; // right = 2*i + 2
// If left child is larger than root
if (l < n && arr[l] > arr[largest])
largest = l;
// If right child is larger than largest so far
if (r < n && arr[r] > arr[largest])
largest = r;
// If largest is not root
if (largest != i) {
swap(arr[i], arr[largest]);
// Recursively heapify the affected sub-tree
heapify(arr, n, largest);
}
}
// main function to do heap sort
void heapSort(int arr[], int n)
{
// Build heap (rearrange array)
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
// One by one extract an element from heap
for (int i = n - 1; i > 0; i--) {
// Move current root to end
swap(arr[0], arr[i]);
// call max heapify on the reduced heap
heapify(arr, i, 0);
}
}
// Returns true if any two lines intersect.
bool isIntersect(Segment arr[], int n)
{
// Pushing all points to a vector of events
vector<Event> e;
for (int i = 0; i < n; ++i) {
e.push_back(Event(arr[i].left.x, arr[i].left.y, true, i));
e.push_back(Event(arr[i].right.x, arr[i].right.y, false, i));
}
// Sorting all events according to x coordinate.
sort(e.begin(), e.end(), [](Event &e1, Event &e2) {return e1.x < e2.x;});
// For storing active segments.
set<Event> s;
// Traversing through sorted points
for (int i=0; i<2*n; i++)
{
Event curr = e[i];
int index = curr.index;
// If current point is left of its segment
if (curr.isLeft)
{
// Get above and below points
auto next = s.lower_bound(curr);
auto prev = pred(s, next);
// Check if current point intersects with
// any of its adjacent
if (next != s.end() && doIntersect(arr[next->index], arr[index]))
return true;
if (prev != s.end() && doIntersect(arr[prev->index], arr[index]))
return true;
// Insert current point (or event)
s.insert(curr);
}
// If current point is right of its segment
else
{
// Find the iterator
auto it = s.find(curr);
// Find above and below points
auto next = succ(s, it);
auto prev = pred(s, it);
// If above and below point intersect
if (next != s.end() && prev != s.end())
if (doIntersect(arr[prev->index], arr[next->index]))
return true;
// Return current point
s.erase(curr);
}
}
return false;
}
// Driver code
int main() {
Segment arr[] = { {{0, 0}, {0, 4}}, {{1, 0}, {5, 0}}};
int n = sizeof(arr)/sizeof(arr[0]);
heapSort(arr, n);
cout << isIntersect(arr, n);
return 0;
}
函数heapSort
声明为
void heapSort(int arr[], int n);
即其第一个参数的类型为int arr[]
,编译器将其调整为int *
.
但是您调用的函数传递的是 Segment[2]
类型的数组作为第一个参数
Segment arr[] = { {{0, 0}, {0, 4}}, {{1, 0}, {5, 0}}};
int n = sizeof(arr)/sizeof(arr[0]);
heapSort(arr, n);
并且没有从类型Segment[2]
(用作函数参数的数组类型arr
)到类型int *
(第一个数组的类型)的隐式转换函数的参数)在编译器将第一个参数 int[]
的类型隐式调整为类型 int *
之后。
解决方案之一是将函数 heapSort
重写为模板函数,例如 like
template <typename T>
void heapSort( T arr[], int n);
在这种情况下,您将需要重写函数 heapSort
也作为模板函数使用的其他函数,