调代码大挑战!

题目:试调以下代码。调出来的人将被颁发“代码巨佬”奖项。

目标:给定一些点对,求他们两两之间的欧几里得距离。

注意:本挑战不是做出以上目标就能完成的,而是需要答出为什么以下代码错误并指出如何修改。

有答案请在本帖下面回复,我会在 8月 6 日之前 24h 之内回复 WA / AC。

#include <iostream>
#include <cmath>
#include <vector>
using namespace std;

struct point {
    float x, y;
};

float distance(point* p1, point* p2)
{
    return sqrt((p1->x - p2->x) * (p1->x - p2->x) + (p1->y - p2->y) * (p1->y - p2->y));
}

int main()
{
    vector<point> po;
    point p1 = { 0, 0 }, p2 = { 1, 1 };
    po.push_back(p1); po.push_back(p2);
    for (auto i = po.begin(); i != po.end(); i++)
        for (auto j = po.begin(); j != po.end(); j++)
            cout << distance(i, j) << " ";
}
// Output: 0 1 -1 0
// Expected Output: 0 1.414... 1.414... 0
5 个赞

奖项是勋章马
:laughing:

5 个赞

不是但是是以此贴为证 XD

4 个赞

好吧

5 个赞

@周point * 改为 std::vector<point>::iterator

5 个赞

因为遍历 std::vector 返回的是迭代器而非指针

5 个赞
  1. 自己和自己怎么会有距离的概念 (题意不清)
  2. 迭代器无法正确对应指针
5 个赞
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;

struct point {
    float x, y;
};

float distance(vector<point>::iterator p1, vector<point>::iterator p2)
{
    return sqrt((p1->x - p2->x) * (p1->x - p2->x) + (p1->y - p2->y) * (p1->y - p2->y));
}

int main()
{
    vector<point> po;
    point p1 = { 0, 0 }, p2 = { 1, 1 };
    po.push_back(p1); po.push_back(p2);
    for (auto i = po.begin(); i != po.end(); i++)
        for (auto j = po.begin(); j != po.end(); j++)
            cout << distance(i, j) << " ";
}

迭代器和指针不对应

5 个赞

:)答对了,此贴终结

补充说明:

迭代器不等于指针。他们两个的关系为:

point* ptr;
std::vector<point>::iterator it;
ptr = &*it; // 正确用法

但是,编译器不能使用 &* 这样隐式转换,需要你自己加。因此,按理来说,以上代码会 CE(没有可取函数)。

那为什么是 WA 而不是 CE 呢?这涉及到一个本题另外一个细节:distance(iterator, iterator) 调用了标准库的 std::distance,是另外一个函数。因为我定义的 distance 函数不匹配,因此编译器就默认匹配了 std::distance

看一下标准库的这个神奇函数:

说白了,就是在测试合法性后直接返回 _Last - _First,也就是两个地址的内存距离,而 vector<int> 中当然会输出 0, 1, -1, 0

于是解释完了。

5 个赞

强。

5 个赞

做个图片,我这边给你弄成勋章

5 个赞

啊!!!好激动,感谢老师:)

等下我想一想

3 个赞

到时候私信我哈,弄漂亮一点,不要梗图啥的,热度过去就不好看了

5 个赞