Terence888 发表于 2024-6-18 18:11:14

摩尔投票法看不懂代码,能不能帮我具体例子循环一下

题目:上一节的课后作业我们提到了“摩尔投票法”,这种方法尤其适用于在任意多的选项中找到数量占比最多的那一个。那么这一次我们修改一下要求,编写代码,利用“摩尔投票法”来找出占比数量最多的两个元素(注意:这两个元素的数量都需要超过总数的三分之一)。
正确的代码如下,我看不懂的是循环体的部分,假如major1=1,count1=1,还要再执行count-=1吗
nums =

   

major1 = major2 = nums

count1 = count2 = 0

   

# 对抗阶段

for each in nums:

    if major1 == each:

      count1 += 1

      continue

   

    if major2 == each:

      count2 += 1

      continue

   

    if count1 == 0:

      major1 = each

      count1 = 1

      continue

   

    if count2 == 0:

      major2 = each

      count2 = 1

      continue

   

    count1 -= 1

    count2 -= 1

   

# 统计阶段

if nums.count(major1) > len(nums) / 3:

    print(major1)

if nums.count(major2) > len(nums) / 3:

    print(major2)

FishC 发表于 2024-6-18 18:11:31

好的,让我们来详细解释一下摩尔投票法的代码,以及循环体部分的逻辑。为了更直观地理解,我们会使用具体的例子进行演示。

举个例子,假设输入的列表是 `nums = `。

def findMajorityElements(nums):
    # 初始化候选人和计数器
    major1 = major2 = None
    count1 = count2 = 0

    # 对抗阶段
    for each in nums:
      if major1 == each:
            count1 += 1
            continue

      if major2 == each:
            count2 += 1
            continue

      if count1 == 0:
            major1 = each
            count1 = 1
            continue

      if count2 == 0:
            major2 = each
            count2 = 1
            continue

      count1 -= 1
      count2 -= 1

    # 统计阶段
    result = []
   
    if nums.count(major1) > len(nums) / 3:
      result.append(major1)
    if nums.count(major2) > len(nums) / 3:
      result.append(major2)
   
    return result

# 示例
print(findMajorityElements())

代码执行过程如下:

1. 初始化 `major1`, `major2` 和 `count1`, `count2`。
   major1 = None
   major2 = None
   count1 = 0
   count2 = 0

2. 遍历 `nums` 列表:
   - 第一个元素是 `1`:
   - `count1` 为 `0`,所以 `major1 = 1`, `count1 = 1`。
   - 第二个元素是 `2`:
   - `count2` 为 `0`,所以 `major2 = 2`, `count2 = 1`。

   - 第三个元素是 `3`:
   - 既不是 `major1` 也不是 `major2`,所以 `count1` 和 `count2` 减少:`count1 = 0`, `count2 = 0`。

   - 第四个元素是 `1`:
   - `count1` 为 `0`,所以 `major1 = 1`, `count1 = 1`。

   - 第五个元素是 `1`:
   - `major1` 是 `1`,所以 `count1` 增加:`count1 = 2`。

   - 第六个元素是 `2`:
   - `major2` 是 `2`,所以 `count2` 增加:`count2 = 1`。

   - 第七个元素是 `2`:
   - `major2` 是 `2`,所以 `count2` 增加:`count2 = 2`。

   - 第八个元素是 `1`:
   - `major1` 是 `1`,所以 `count1` 增加:`count1 = 3`。

   - 第九个元素是 `2`:
   - `major2` 是 `2`,所以 `count2` 增加:`count2 = 3`。

3. 最终得到 `major1 = 1`, `major2 = 2`, `count1 = 3`, `count2 = 3`。

4. 统计阶段:
   - `major1` 为 `1`,在 `nums` 中出现了 4 次,超过 1/3,所以输出 `1`。
   - `major2` 为 `2`,在 `nums` 中出现了 4 次,也超过 1/3,所以输出 `2`。

最终结果为 ``。

如果仍有不清楚的地方,欢迎再问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

Terence888 发表于 2024-7-3 16:29:37

进入循环获取第二个元素的时候,不会把major1值覆盖吗?为什么each可以自动赋值给major2

FishC 发表于 2024-7-3 16:30:07

Terence888 发表于 2024-07-03 16:29
进入循环获取第二个元素的时候,不会把major1值覆盖吗 ...

这是个好问题!我们来详细解释一下这个过程,确保您完全理解。

摩尔投票法的关键思想是使用两个候选人(`major1` 和 `major2`)和对应的计数器(`count1` 和 `count2`)去追踪可能的多数元素。以下是代码中的步骤:

def findMajorityElements(nums):
    # 初始化候选人和计数器
    major1 = major2 = None
    count1 = count2 = 0

    # 对抗阶段
    for each in nums:
      if major1 == each:
            count1 += 1
            continue

      if major2 == each:
            count2 += 1
            continue

      if count1 == 0:
            major1 = each
            count1 = 1
            continue

      if count2 == 0:
            major2 = each
            count2 = 1
            continue

      count1 -= 1
      count2 -= 1

    # 统计阶段
    result = []
   
    if nums.count(major1) > len(nums) / 3:
      result.append(major1)
    if nums.count(major2) > len(nums) / 3:
      result.append(major2)
   
    return result

# 示例列表
nums =
print(findMajorityElements(nums))

我们来通过具体例子解释循环的每一步:

假设 `nums = `。

1. 我们开始时,`major1`, `major2` 是 `None`,`count1`, `count2` 是 `0`。
   - `major1 = None`
   - `major2 = None`
   - `count1 = 0`
   - `count2 = 0`

2. 遍历 `nums` 列表:
   - 第一个元素 `1`:
   - `count1` 为 `0`,所以 `major1 = 1`, `count1 = 1`。
   - 第二个元素 `2`:
   - `count2` 为 `0`,所以 `major2 = 2`, `count2 = 1`。
   
   上面这两步,`each` 的值分别赋给了 `major1` 和 `major2`,因为初始时它们的计数器 `count1` 和 `count2` 都是 `0`。

   - 第三个元素 `3`:
   - 既不是 `major1`(`1`)也不是 `major2`(`2`),所以 `count1` 和 `count2` 减少:`count1 -= 1`, `count2 -= 1`,现在 `count1 = 0`, `count2 = 0`。
   - 第四个元素 `1`:
   - `count1` 为 `0`,所以 `major1 = 1`, `count1 = 1`。

   这里您可能会疑惑,为什么 `major1` 不会被覆盖。在上面的例子中,`major1` 在后来的过程中重新被赋值了 `1`,因为 `count1` 降到了 `0`。

   - 第五个元素 `1`:
   - `major1` 是 `1`,所以 `count1 += 1`,现在 `count1 = 2`。

3. 继续遍历:
   - 第六个元素 `2`:
   - `major2` 是 `2`,所以 `count2 += 1`,现在 `count2 = 1`。
   - 第七个元素 `2`:
   - `major2` 是 `2`,所以 `count2 += 1`,现在 `count2 = 2`。
   - 第八个元素 `1`:
   - `major1` 是 `1`,所以 `count1 += 1`,现在 `count1 = 3`。
   - 第九个元素 `2`:
   - `major2` 是 `2`,所以 `count2 += 1`,现在 `count2 = 3`。

通过上面的步骤,您可以看到,`major1` 和 `major2` 只在它们对应的计数器为 `0` 时才会被新的元素覆盖。这就是为什么 `each` 能够自动赋值给 `major2`,因为在 `count2` 为 `0` 的那次循环中,`major2` 还没有被赋值。

总结一下:当 `count1` 或 `count2` 为 `0` 时,就表示当前跟踪的候选人已经无力再对抗其他元素了,这时候就会赋予新的元素。如果 `count` 不为 `0`,则会根据是否与 `major1` 或 `major2` 相等决定增减计数器的值。

希望这样的解释能帮助您理解这个过程!如果还有任何疑问,请继续问我。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: 摩尔投票法看不懂代码,能不能帮我具体例子循环一下