我正在阅读" C ++中的算法"由Robert Sedgewick和我进行了这个练习:用另一种编程语言中的算法减半,用路径压缩重写这个权重的快速联合。
该算法用于检查是否连接了两个对象,例如,对于像1 - 2,2 - 3和1 - 3这样的条目,前两个条目创建新连接,而在第三个条目中,1和3已连接,因为3可以从1:1 - 2 - 3到达,因此第三个条目不需要创建新连接。
很抱歉,如果算法描述不可理解,那么英语不是我母亲的语言。
所以这是算法本身:
#include <iostream>
#include <ctime>
using namespace std;
static const int N {100000};
int main()
{
srand(time(NULL));
int i;
int j;
int id[N];
int sz[N]; // Stores tree sizes
int Ncount{}; // Counts the numbeer of new connections
int Mcount{}; // Counts the number of all attempted connections
for (i = 0; i < N; i++)
{
id[i] = i;
sz[i] = 1;
}
while (Ncount < N - 1)
{
i = rand() % N;
j = rand() % N;
for (; i != id[i]; i = id[i])
id[i] = id[id[i]];
for (; j != id[j]; j = id[j])
id[j] = id[id[j]];
Mcount++;
if (i == j) // Checks if i and j are connected
continue;
if (sz[i] < sz[j]) // Smaller tree will be
// connected to a bigger one
{
id[i] = j;
sz[j] += sz[i];
}
else
{
id[j] = i;
sz[i] += sz[j];
}
Ncount++;
}
cout << "Mcount: " << Mcount << endl;
cout << "Ncount: " << Ncount << endl;
return 0;
}
我知道一点点蟒蛇,所以我选择它进行这项练习。这是得到的:
import random
N = 100000
idList = list(range(0, N))
sz = [1] * N
Ncount = 0
Mcount = 0
while Ncount < N - 1:
i = random.randrange(0, N)
j = random.randrange(0, N)
while i is not idList[i]:
idList[i] = idList[idList[i]]
i = idList[i]
while j is not idList[j]:
idList[j] = idList[idList[j]]
j = idList[j]
Mcount += 1
if i is j:
continue
if sz[i] < sz[j]:
idList[i] = j
sz[j] += sz[i]
else:
idList[j] = i
sz[i] += sz[j]
Ncount += 1
print("Mcount: ", Mcount)
print("Ncount: ", Ncount)
但是我偶然发现了这个有趣的细微差别:当我将N设置为100000或更多时,C ++版本似乎比python版本慢很多 - 在python中完成任务的时间大约需要10秒而C ++版本这样做很慢,我不得不关闭它。
所以我的问题是:原因是什么?这是否因为rand()%N和random.randrange(0,N)的不同而发生?或者我刚做错了什么?
如果有人能够向我解释这一点,我将非常感激,提前谢谢!
答案 0 :(得分:3)
这些代码做了不同的事情。
您必须将python中的数字与==
进行比较。
>>> x=100000
>>> y=100000
>>> x is y
False
可能还有其他问题,无法检查。您是否比较了应用程序的结果?
答案 1 :(得分:2)
如上所述,代码并不相同,特别是在使用is
vs ==
时。
查看以下Pyhton代码:
while i is not idList[i]:
idList[i] = idList[idList[i]]
i = idList[i]
评估 0或1次。为什么?。因为如果while
第一次评估为True
,那么i = idList[i]
会在第二次传递中生成条件True
,因为现在i
肯定是一个数字在is
idList
等效c++
for (; i != id[i]; i = id[i])
id[i] = id[id[i]];
此处代码检查相等而非存在,并且运行它的次数不固定为 0或1
所以是的...使用is
vs ==
会产生巨大差异,因为在Python中您正在测试实例相等和包含在中,而不是在等价的意义上测试简单的相等。
上面的Python和C ++的比较就像比较苹果和梨。
注意:问题的简短答案是: Python版本的运行速度要快得多,因为它比C ++版本要少得多