鱼C论坛

 找回密码
 立即注册
查看: 322|回复: 3

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

[复制链接]
发表于 2024-6-18 18:11:14 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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

   

major1 = major2 = nums[zxsq-anti-bbcode-0]

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)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-6-18 18:11:31 | 显示全部楼层
好的,让我们来详细解释一下摩尔投票法的代码,以及循环体部分的逻辑。为了更直观地理解,我们会使用具体的例子进行演示。

举个例子,假设输入的列表是 `nums = [1, 2, 3, 1, 1, 2, 2, 1, 2]`。
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, 2, 3, 1, 1, 2, 2, 1, 2]))

代码执行过程如下:

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`。

最终结果为 `[1, 2]`。

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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-7-3 16:29:37 | 显示全部楼层
进入循环获取第二个元素的时候,不会把major1值覆盖吗?为什么each可以自动赋值给major2
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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 = [1, 2, 3, 1, 1, 2, 2, 1, 2]
print(findMajorityElements(nums))

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

假设 `nums = [1, 2, 3, 1, 1, 2, 2, 1, 2]`。

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 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-22 23:41

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表