这是我正在使用的扫线算法的C++代码。我正在使用HeapSort对点进行排序。但我得到以下2个错误:
第214行:字符5:错误:调用“堆排序”没有匹配函数
heapSort(arr, n);
第134行:字符6:注意:候选函数不可行:第一个参数没有已知的从“segment[2]”到“int*”的转换
void heapSort(int arr[],int n)
产生1个错误。
我不知道为什么它会抛出两个错误。
// 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);
并且在编译器将第一个参数int[]
的类型隐式调整为类型int*
之后,没有从类型segment[2]
(用作函数参数的数组arr
的类型)到类型int*
(函数的第一个参数的类型)的隐式转换。
解决方案之一是将函数heapsort
重写为模板函数,例如
template <typename T>
void heapSort( T arr[], int n);
在这种情况下,您将需要重写函数heapsort
也作为模板函数使用的其他函数,
我试图使用std::cout打印一组对,但它没有编译。我在Xcode9上使用C++14。错误发生在行 错误:二进制表达式(“ostream”(又名“basic_ostream”)和“const value_type”(又名“const std::__1::pair”)的操作数无效)
为什么在添加捕获元素时,下面的lambda不符合签名? 但这会吗? 签名:
我一直在尝试编译,并玩了一圈的和数,但仍然不能弄清楚错误是什么。有什么想法吗? 标题:
但是,如果Terminal中没有提供,我不知道如何(或者是否能够)为其设置默认值。像这样简单的东西不起作用。这里的一个解决方案是根据的内容或大小在函数中设置变量。但我不知道有没有更好的办法做到这一点。 因此,我正在寻找一种方法来使用来自终端的参数调用一个函数,其中需要一个数字(在本例中为2),而其余的是可选的,并设置为默认值。
我的问题是为什么编译器在第一种情况下不显示错误,而在第二种情况下显示错误?以下是完整的代码:
我有一个函数,它使用Boost进行base64编码。它有两个模板参数:一个用于输入的容器类型,另一个用于输出的容器类型。这允许您使用提供二进制数据,但可以返回。 这是代码: 用法示例: 这里有活样品 请注意,在上面的示例中,我仍然必须为输出容器提供模板参数,即使它与输入容器的类型相同。在这些场景中,我希望模板参数是可选的,而是使用由推导的类型。我不确定我可以执行什么变通或调整来获得这种界面,但很高