Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何找到重复至少N/2次的数组元素?_C_Algorithm - Fatal编程技术网

C 如何找到重复至少N/2次的数组元素?

C 如何找到重复至少N/2次的数组元素?,c,algorithm,C,Algorithm,给定一个包含N个元素的数组。我们知道其中一个元素自身至少重复N/2次 我们对其他元素一无所知。它们可能重复,也可能是唯一的 有没有办法找出在一次传递中至少重复N/2次或可能是O(N)的元素 不得使用额外空间。 如果不使用额外的空间,似乎不可能计算任何东西。你必须在某处至少存放一个柜台。如果你的意思是说你不能使用超过O(n)的空间,那么这应该是相当容易的 一种方法是从原始列表中创建第二个仅包含唯一对象的列表。然后,创建与第二个列表长度相同的第三个列表,其中包含列表中每个项目出现次数的计数器 另一种

给定一个包含N个元素的数组。我们知道其中一个元素自身至少重复N/2次

我们对其他元素一无所知。它们可能重复,也可能是唯一的

有没有办法找出在一次传递中至少重复N/2次或可能是O(N)的元素

不得使用额外空间。


如果不使用额外的空间,似乎不可能计算任何东西。你必须在某处至少存放一个柜台。如果你的意思是说你不能使用超过O(n)的空间,那么这应该是相当容易的

一种方法是从原始列表中创建第二个仅包含唯一对象的列表。然后,创建与第二个列表长度相同的第三个列表,其中包含列表中每个项目出现次数的计数器


另一种方法是对列表进行排序,然后找到最大的连续部分。

st0le回答了这个问题,但这里有一个5分钟的实现:

#include <stdio.h>

#define SIZE 13

int boyerMoore(int arr[]) {
    int current_candidate = arr[0], counter = 0, i;
    for (i = 0; i < SIZE; ++i) {
        if (current_candidate == arr[i]) {
            ++counter;
            printf("candidate: %i, counter: %i\n",current_candidate,counter);
        } else if (counter == 0) {
            current_candidate = arr[i];
            ++counter;
            printf("candidate: %i, counter: %i\n",current_candidate,counter);
        } else {
            --counter;
            printf("candidate: %i, counter: %i\n",current_candidate,counter);
        }
    }
    return current_candidate;
}

int main() {
    int numbers[SIZE] = {5,5,5,3,3,1,1,3,3,3,1,3,3};
    printf("majority: %i\n", boyerMoore(numbers));
    return 0;
}
#包括
#定义尺寸13
内部boyerMoore(内部arr[]{
int当前_候选者=arr[0],计数器=0,i;
对于(i=0;i

这里有一个有趣的解释(至少比读报纸有趣):

因为其他用户已经发布了算法,我不再重复了。但是,我提供了一个简单的解释,说明它为什么会起作用:

考虑下图,它实际上是一个非偏振光图:

中间的每个箭头代表不同的候选人。想象一下,箭头上的某个点代表计数器和候选人。最初计数器为零,因此它从中心开始。
当找到当前候选对象时,它将沿着该箭头的方向移动一步。如果发现不同的值,计数器将向中心移动一步。

如果存在多数值,则超过一半的移动将朝向该箭头,因此该算法将以当前候选人为多数值结束。

Boyer-Moore多数投票算法无法在下面的输入数组中找到正确的多数

整数[大小]={1,2,3,4,1,2,3,4,1,2,3,4}


整数[大小]={1,2,3,4,1,2,3,4,1,2,3,4,1}

这段代码的实现方式与我们查找元素大部分的方式类似

int find(int* arr, int size)
{ 
int count = 0, i, m;
  for (i = 0; i < size; i++) 
  {
    if (count == 0)
        m = arr[i];
    if (arr[i] == m) 
        count++;
    else
        count--;
   }
    return m;
}
int-find(int*arr,int-size)
{ 
int count=0,i,m;
对于(i=0;i
使用ffao建议的修改对Davi的回复:

public class MaxRepeated {

    public static void main(final String[] args) {
        maxRepeatedElement(new int[]{1, 2, 1, 2, 3, 2, 3, 1});
        maxRepeatedElement(new int[]{1, 2, 1, 2, 3, 1, 3, 1});
        maxRepeatedElement(new int[]{1, 2, 1, 2, 4, 1, 1, 3, 1, 3, 1});
        maxRepeatedElement(new int[]{1, 2, 1, 2, 2, 1, 2, 3, 1, 2, 1, 2});
    }

    private static int maxRepeatedElement(final int[] arr) {

        int current_candidate = arr[0];
        int previous_candidate = arr[0];
        int counter = 0, i;
        for (i = 0; i < arr.length; ++i) {
            if (current_candidate == arr[i]) {
                ++counter;
            } else if (counter == 0) {
                previous_candidate = current_candidate;
                current_candidate = arr[i];
                ++counter;
            } else {
                --counter;
            }
            System.out.printf("  candidate: %d, counter: %d\n", current_candidate, counter);
        }

        if (counter == 0) {
            System.out.printf(" possible: %d or %d with net freq %d \n", current_candidate, previous_candidate, counter);
            final int f1 = frequency(arr, current_candidate);
            final int f2 = frequency(arr, previous_candidate);
            final int halfLen = arr.length / 2 + (arr.length % 2 == 0 ? 0 : 1);
            if (f1 >= halfLen || f2 >= halfLen) {
                if (f1 > f2) {
                    System.out.printf("majority: %d with freq %d \n", current_candidate, f1);
                } else {
                    System.out.printf("majority: %d with freq %d \n", previous_candidate, f2);
                }
            } else {
                System.out.printf("NO majority! \n");
            }
        } else {
            System.out.printf("majority: %d with freq %d \n", current_candidate, frequency(arr, current_candidate));
        }
        return current_candidate;
    }

    private static int frequency(final int[] arr, final int candidate) {
        int counter = 0;
        for (int c : arr) {
            counter += candidate == c ? 1 : 0;
        }
        return counter;
    }
}
public类{
公共静态void main(最终字符串[]args){
maxRepeatedElement(新的int[]{1,2,1,2,3,2,3,1});
maxRepeatedElement(新的int[]{1,2,1,2,3,1,3,1});
maxRepeatedElement(新的int[]{1,2,1,2,4,1,1,3,1,3,1});
maxRepeatedElement(新的int[]{1,2,1,2,2,2,3,1,2,1,2,1,2});
}
私有静态int maxRepeatedElement(最终int[]arr){
int当前_候选者=arr[0];
int previous_候选者=arr[0];
int计数器=0,i;
对于(i=0;i=半透镜| | f2>=半透镜){
如果(f1>f2){
System.out.printf(“多数:%d,频率为%d\n”,当前候选,f1);
}否则{
System.out.printf(“多数:%d,频率为%d\n”,前一个候选,f2);
}
}否则{
System.out.printf(“无多数!\n”);
}
}否则{
System.out.printf(“多数:%d,频率为%d\n”,当前_候选,频率(arr,当前_候选));
}
返回当前_候选人;
}
专用静态整数频率(最终整数[]arr,最终整数候选){
int计数器=0;
用于(内部c:arr){
计数器+=候选者==c?1:0;
}
返回计数器;
}
}
试试这个:

#include<iostream>
using namespace std;
int main()
{
    int counter=0;
    int a[]={10, 11, 5, 27, 4, 2, 7, 5, 7, 11, 9, 5, 5, 4, 10, 7, 5, 3, 7, 5};
    for(int i = 0; i < 20; i++)
    {
        if(a[i]==5)
        counter++;
    }
    cout << "it appears " << counter << " times";
}
#包括
使用名称空间std;
int main()
{
int计数器=0;
inta[]={10,11,5,27,4,2,7,5,7,11,9,5,5,4,10,7,5,3,7,5};
对于(int i=0;i<20;i++)
{
如果(a[i]==5)
计数器++;
}

这是家庭作业吗?如果是,请将其标记为家庭作业。不能使用额外的空间,或者只能使用O(1)空间?迭代数组必须使用一些空间。@威尔:这不是家庭作业……我已经尝试了很多次,但找不到更好的方法……严格来说,这个问题无法在
O(1)
#include<iostream>
using namespace std;
int main()
{
    int counter=0;
    int a[]={10, 11, 5, 27, 4, 2, 7, 5, 7, 11, 9, 5, 5, 4, 10, 7, 5, 3, 7, 5};
    for(int i = 0; i < 20; i++)
    {
        if(a[i]==5)
        counter++;
    }
    cout << "it appears " << counter << " times";
}