C++ 代码在我的系统中运行良好,但coursera自动签名器给了我未知信号
任务——此代码问题的目标是实现二进制搜索算法 输入格式——输入的第一行包含整数n和序列a0C++ 代码在我的系统中运行良好,但coursera自动签名器给了我未知信号,c++,algorithm,c++11,binary-search,coursera-api,C++,Algorithm,C++11,Binary Search,Coursera Api,任务——此代码问题的目标是实现二进制搜索算法 输入格式——输入的第一行包含整数n和序列a0
int binary_search(const vector<long long> &a, long long x) {
size_t left = 0, right = (size_t)a.size()-1;
size_t mid = 0;
while(left<=right){
mid = (left+right)/2;
if(x < a[mid]){
right = mid-1;
}
else if(x > a[mid]){
left = mid+1;
}
else return mid;
}
return -1;
}
int main() {
size_t n;
std::cin >> n;
vector<long long> a(n);
for (size_t i = 0; i < a.size(); i++) {
std::cin >> a[i];
}
size_t m;
std::cin >> m;
vector<long long> b(m);
for (size_t i = 0; i < m; ++i) {
std::cin >> b[i];
}
for (size_t i = 0; i < m; ++i) {
//replace with the call to binary_search when implemented
std::cout << binary_search(a, b[i]) << ' ';
}
}
不知道Coursera测试用例,但您的代码肯定会失败,有两个边缘用例: 1) 空的输入向量
a
->您将在第行right=(size\t)a.size()中得到下溢代码>。换句话说,right
将成为一个较大的正值,您将进入循环并尝试检索a[mid]
,其中mid
将是一些较大的正值索引。当然,尝试从空数组中获取该值会导致错误
2) left+right
太大->溢出->在许多二进制搜索实现中发现的bug,甚至在书籍中:)使用mid=(right-left)/2+left
通过将所有大小
更改为长
,它可以正常工作。
未知信号11表示分段故障,即内存访问出现问题。
因此,将所有size\u t
更改为long
可增加向量的范围,从而允许输入更多值,从而解决内存访问问题。如果向量的大小为2,则初始化左=0
,右=1
和中=0
<代码>在Constaints段落左侧,OP提供了一些关于测试的信息cases@Damien您是对的,那么这两个边缘情况不应该出现在这个测试套件中。在输入格式中,已经提到了1@prakirikhotiya请更正您的问题,将10^4
而不是104
,和10^9
而不是109
@MiljenMikic我已经尝试了您建议的两种可能的更改。仍然得到相同的错误。可能有一些内存泄漏或我无法弄清楚的东西。我想不相关,但为什么要对小于109的值使用long long?也许你的意思是10^9?不相关但只是好奇,这是哪一个过程?甚至10⁹ 将适合普通的老式int
(它至少在32位平台上运行)。2¹⁰ ≅ 10³,所以10⁹ ≅ 2³⁰ 在32位或更多位平台上,可以使用-<代码> int /代码> 2×2……胡席维格算法工具箱由加利福尼亚大学圣地亚哥分校和国家研究型大学经济学院SCP首选:STD::SIEZHETT可以存储任何类型(包括数组)的理论上可能的对象的最大大小。我不明白发生了什么@Damien补充了这些信息,原因很清楚:一些size\u t
值在某一点上应该是负值(但由于无符号环绕,反而是一个巨大的正值)。在程序中只有两个地方可以发生这种情况。@MaxLanghof现在确实清楚了。回答也不错。我现在记得Bjarne Stroustrup的一项建议,即在对无符号int执行操作时应避免使用无符号int。实际上,如果对任何大小的向量x
,都会发生这种情况,因为right
将一直减小,直到达到这个值为止。
Failed case #4/36: unknown signal 11 (Time used: 0.00/1.00, memory used: 40071168/536870912.)