当前位置: 首页 > 知识库问答 >
问题:

为什么当索引为0和1时不进行交换?

唐向荣
2023-03-14

我有一个无序数组,由连续的整数[1,2,3,...,n]组成,没有任何重复项。允许交换任意两个元素。我需要找到按升序对数组排序所需的最小交换数。

a = [4,3,1,2]
b = a[:]
swap = 0
for p in a:
  if (p!= b[p-1]):
    b[p-1], b[b.index(p)] =  b[b.index(p)], b[p-1]
    swap+=1
print(swap)
p = 4
idx1= 3 idx2= 0
b= [2, 3, 1, 4]
swap = 1
p = 3
idx1= 2 idx2= 1
b= [2, 1, 3, 4]
swap = 2
p = 1
idx1= 0 idx2= 1
b= [2, 1, 3, 4]
swap = 3
p = 2
idx1= 1 idx2= 0
b= [1, 2, 3, 4]
swap = 4

在本例中,您可以看到,对于p=1,当索引为0和1时,交换不发生。

我改变了b[p-1],b[b.index(p)]的顺序,我不再有同样的问题了,但我不明白原因。

共有1个答案

赵英哲
2023-03-14

我以前也遇到过同样的问题,一时糊涂。造成这种情况的原因是多重赋值的顺序。

b[p-1], b[b.index(p)] =  b[b.index(p)], b[p-1]

实际上,多重赋值并不完全是同时赋值。这背后的打包和解包机制。因此,它将首先更改b[p-1],而b[b.index(p)]中的b.index(p)将在p=1IDX1=0IDX2=1的情况下找到一个新索引,该索引为p-1

如果你改变分配顺序,它会很好地工作。

b[b.index(p)], b[p - 1] = b[p - 1], b[b.index(p)]
idx1, idx2 = p - 1, b.index(p)
b[idx1], b[idx2] = b[idx2], b[idx1]

您可以在这里参考我的相关问题:Python中多项赋值背后的机制

顺便说一句,我认为您的算法在这里效率很低,为了减少交换时间,但是使用了O(n)index操作,并且在这里复制了一个数组。我想你可以用同样的想法,只是在折日数组中交换。

 类似资料:
  • 问题内容: C语言约定从0开始计数数组索引。为什么inode编号从1开始而不是0? 如果保留索引节点0供某些特殊用途,那么索引节点0的意义是什么? 问题答案: 通常,保留索引节点0,因为返回值0通常表示发生错误。Linux内核中的多种方法(尤其是在所有文件系统共享的VFS层中)均返回ino_t,例如find_inode_number。 还有更多保留的索引节点号。例如在ext2中: 和EXT3有:

  • 问题内容: (为什么/什么时候)最好用于索引?在我刚刚找到的文档中 ->这是否总是在索引NumPy / Cython时应始终使用-数组/视图? ->例如,这样我就不能使用 问题答案: 已签名。请参阅PEP 353,其中说: “引入了一个新类型Py_ssize_t,其大小与编译器的size_t类型相同,但已签名。如果可用,它将是ssize_t的typedef。” 您应该使用索引。我在Cython文档

  • 问题内容: 为什么在Python中等于?它不应该像那样抛出异常吗? 问题答案: Wikipedia对历史进行了有趣的报道,并对以下内容的价值有不同的看法: 至少从19世纪初期开始,辩论一直在进行。当时,大多数数学家都同意,直到1821年,柯西(Cauchy)以及诸如未定义形式的表格之类的表达式才被列出。在1830年代,利比里(Libri)发表了令人信服的论点,莫比乌斯(Möbius)站在他身边。

  • 问题内容: 我有一张表,其中有一个名为的整数列。我在该列上有一个索引。 但是似乎Postgres不想使用我的索引: 知道为什么会这样吗? 问题答案: 因为: 您选择的行太多了,以至于读取整个表都比较便宜。

  • 问题内容: 运行下面的代码结果为0? 问题答案: 两个操作数(1和3)是整数,因此使用整数算术(此处为除法)。将结果变量声明为double只会导致除法后发生隐式转换。 当然,整数除法会返回除法四舍五入的真实结果。因此,0.333…此处的结果四舍五入为0。(请注意,处理器实际上不进行任何舍入,但是您仍然可以这样考虑。) 另外,请注意,如果两个操作数(数字)均以浮点数给出;3.0和1.0,甚至只是第一