代码在我的系统中运行良好,但 coursera autograder 给了我未知的信号

Posted

技术标签:

【中文标题】代码在我的系统中运行良好,但 coursera autograder 给了我未知的信号【英文标题】:Code is working fine in my system but coursera autograder is giving me unknown signal 【发布时间】:2019-06-06 07:30:42 【问题描述】:

任务 -- 本代码题的目标是实现二分查找算法。

输入格式 -- 输入的第一行包含一个整数 n 和一个序列 a0

约束 -- 1 ≤ n,k ≤ 10^4; 1 ≤ a[i] ≤ 10^9 对于所有 0 ≤ i

输出格式 -- 对于从 0 到 k-1 的所有 i,输出一个索引 0 ≤ j ≤ n-1 使得 aj = bi 或 -1 如果没有这样的索引。

我正在使用带有 c++11 编译器的代码块。 我已经尝试过压力测试并在我的系统中得到了正确的结果。 但是 coursera autograder 给了我未知的信号 11。 在某些问题中,它会给出未知信号 8。 谁能告诉我这背后的可能原因。

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]) << ' ';
  

我在自动评分器中得到的实际结果。

Failed case #4/36: unknown signal 11 (Time used: 0.00/1.00, memory used: 40071168/536870912.)

【问题讨论】:

我猜不相关,但你为什么使用 long long 来表示小于 109 的值? 也许你的意思是 10^9 ? 不相关,只是好奇,它是哪个课程? 即使是 10⁹ 也适合普通的旧 int(它至少在 32 位平台上运行)。 2¹⁰ ≅ 10³,所以 10⁹ ≅ 2³⁰ 和 int 在 32 位或更多位平台上可以容纳 -2³¹ … 2³¹-1。 @JuniverHazoic 加州大学圣地亚哥分校和国立研究大学高等经济学院的算法工具箱 【参考方案1】:

如果向量有例如大小为 2,然后初始化 left = 0right = 1mid = 0left &lt;= right 所以你计算mid = 0 并检查是否x &lt; a[0]如果发生这种情况,您现在设置right = -1。在无符号算术中,这是一个非常大的数字。您的循环继续,因为0 &lt;= really large number,您计算mid = half of really large number 并访问那里的向量。那是 UB,会让你的程序被杀死。

切换到有符号类型意味着right = -1 确实小于left = 0 并终止循环。

【讨论】:

实际上,如果x &lt; a[0] 用于任何大小的向量,就会发生这种情况,因为right 会一直减少,直到达到这一点。【参考方案2】:

不了解 Coursera 测试用例,但您的代码肯定会因两个极端情况而失败:

1) 空输入向量a -> 你将在right = (size_t)a.size()-1; 行出现下溢。换句话说,right 将成为一个大的正值,您将进入循环并尝试检索 a[mid] 其中mid 将是一些大的正索引。当然,尝试从空数组中获取它会导致错误。

2) left+right 太大 -> 溢出 -> 在许多二进制搜索实现中发现错误,甚至在书籍中:) 改用 mid = (right - left) / 2 + left;

【讨论】:

Constaints 段落中,OP 提供了一些关于测试用例的信息 @Damien 你是对的,那么这两个极端情况不应该出现在这个测试套件中。 输入格式中已经提到1 &lt;= n,k &lt;= 10^4。所以我认为这可能不是问题,但第二个听起来是正确的。 @PrakirtiLakhotiya 请更正您的问题,用10^4 代替104,用10^9 代替109 @MiljenMikic 我已经尝试了您建议的两种可能的更改。仍然得到同样的错误。也许有一些内存泄漏或我无法弄清楚的东西。【参考方案3】:

通过将所有size_t 更改为long,它可以正常工作。 unknown signal 11表示segmentation fault,即内存访问有问题。 因此,将所有size_t 更改为long 会增加vector 的范围,从而让更多的值可以解决内存访问问题。

【讨论】:

cppreference:std::size_t 可以存储理论上可能的任何类型(包括数组)对象的最大大小。我不明白会发生什么! @Damien 有了这些附加信息,原因就很清楚了:一些size_t 值在某些时候应该是负数(但由于无符号环绕,它是一个巨大的正值)。程序中只有两个地方会发生这种情况。 @MaxLanghof 现在确实清除了。也很好回答。我现在记得 Bjarne Stroustrup 的建议,即在对其执行操作时应避免使用 unsigned int。

以上是关于代码在我的系统中运行良好,但 coursera autograder 给了我未知的信号的主要内容,如果未能解决你的问题,请参考以下文章

Edward Angel 示例 OpenGL 代码:在 Lenovo X60 上运行良好,但不能在我的桌面上呈现窗口(英特尔高清显卡)

代码在我的系统上运行良好,但是当我将它提交给应该检查它的机器人时会导致堆栈粉碎错误

在Mac终端中运行python。有时它运行良好,有时它会卡住而没有响应

qapps 运行良好但断点有时会产生分段错误

代码在我的计算机上运行良好,但在“hackerearth”平台上在线运行时出现 NullPointerException

如何从存储过程中获取结果,过程运行良好但 php 返回 null