编程之美:寻找发帖"水王" 扩展

1.问题描述

快速找出发帖超过一半的的ID

问题变型:

现在有一个数组,已知一个数出现的次数超过了一半,请用最小的复杂度的算法找出这个数。

问题扩展:

有三个发帖很多的ID,他们的发帖数目超过了帖子总数目的1/4,请从发帖ID列表中找出它们

2.分析与解法

每次从列表中删除两个不同的ID,那么剩下的ID列表中,“水王”的ID出现次数仍然超过剩余数目的一半,因此每次删除两个不同的ID,直到剩下的所有ID都相同,那么剩下的就是水王的ID。

我们可以设置一个candidate和一个计数器nTimes,candidate为ID列表第一个ID,nTimes初始值为0,遍历整个ID列表,当遍历的ID与candidate相同,nTimes++,如果不同则nTimes--,此时相当于成对删除不同的ID,当nTimes又为0的时候,更新candidate,将其设置为当前遍历的ID,因为有一个ID总是在剩余中的ID超过一半,所以最后nTimes大于0,candidate即为所求。

int find(int* ID, int n)
{
    int nTimes = 0, i, candidate;
    
    for(i = 0; i < 0;i++)
    {
          if(nTimes == 0)
          {
              candidate = ID[i];
          }
          else
          {
              if(candidate == ID[i])
              {
                  nTimes++;
              }
              else
              {
                  nTimes--;
              }
          }
    }
    return candidate;
}

 扩展问题:依据以上的原理,我们可以以四个为单位进行比较,如果四个ID均不相同则删掉四个ID,那么所要求的三个ID,仍然超过其余ID的1/4。

相应的代码实现:

void find3(int * ID, int n)  
{  
    int candidate[3]; 
    int nTimes[3] = {0};  
    int i;  
  
    for (i = 0; i < n; i++)  
    {  
        if(nTimes[0] == 0)  
        {  
            if(ID[i] == candidate[1])  
                nTimes[1]++;  
            else if (ID[i] == candidate[2])  
                nTimes[2]++;  
            else  
            {  
                candidate[0] = ID[i];  
                nTimes[0]++;  
            }  
        }  
        else if (nTimes[1] == 0)  
        {  
            if(ID[i] == candidate[0])  
                nTimes[0]++;  
            else if (ID[i] == candidate[2])  
                nTimes[2]++;  
            else  
            {  
                candidate[1] = ID[i];  
                nTimes[1]++;  
            }  
        }  
        else if (nTimes[2] == 0)  
        {  
            if(ID[i] == candidate[0])  
                nTimes[0]++;  
            else if (ID[i] == candidate[1])  
                nTimes[1]++;  
            else  
            {  
                candidate[2] = ID[i];  
                nTimes[2]++;  
            }  
        }  
        else  
        {  
            if(ID[i] == candidate[0])  
                nTimes[0]++;  
            else if(ID[i] == candidate[1])  
                nTimes[1]++;  
            else if(ID[i] == candidate[2])  
                nTimes[2]++;  
            else  
                nTimes[0]--, nTimes[1]--, nTimes[2]--;  
        }  
    }  
    printf("三个水王ID分别是:%d,%d,%d\n", candidate[0], candidate[1], candidate[2]);  
}

 

转载于:https://www.cnblogs.com/tgkx1054/archive/2012/11/29/2795549.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CAN总线是一种通信协议,用于连接多个节点,如传感器和执行器,构成分布式监控系统。它可以任意插在PC AT XT兼容机上,方便地实现分布式监控系统。利用FPGA实现CAN总线通信控制器具有很大的应用价值。 FPGA是一种可编程逻辑芯片,可以根据需要重新配置其内部电路,使其具备特定的功能。基于FPGA的CAN总线控制器的设计可以通过多篇文章进行详细介绍。在设计过程中,首先需要进行CAN总线协议的解析,并确定CAN通信控制器程序的基本框架。 当需要使用CAN总线或接口时,我们可以根据FPGA的特点选择不同的方案。这些方案的区别在于其他厂商在制作FPGA芯片时制作了哪一层的电路。通过选择适合的方案,我们可以实现CAN通信。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [基于FPGA的CAN总线控制器的设计(上)](https://blog.csdn.net/qq_40310273/article/details/116567881)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [【科普】CAN总线介绍及FPGA实现方案简介](https://blog.csdn.net/Pieces_thinking/article/details/121280020)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值