c++ - 查找数组重复单元的最简单方法是什么?

标签 c++ arrays algorithm language-agnostic

例如,重复单元

1,1,1,1,1

是1,

重复单位

1,3,2,1,3,2,1,3,2

是 1,3,2

重复单位

1,3,2,1,3,9,1,3,2

是 1,3,2,1,3,9,1,3,2

我尝试这样的想法:

1.尝试重复单元测试的次数从1开始,直到数组大小

2.只尝试数组大小的倍数,例如:n

3.检查n是否为重复单元的大小,例如:假设测试重复单元为3,则检查是否

a[0]==a[3*1],a[1]==a[1+3*1],a[2]==a[2+3*1]
a[0]==a[3*2],a[1]==a[1+3*2],a[2]==a[2+3*2]
a[0]==a[3*r],a[1]==a[1+3*r],a[2]==a[2+3*r]
  1. 如果当前测试数是repeat unit,break,i的当前值是repeat unit的大小

我尝试将其转换为代码:

#include <stdio.h>
int main(){
    int a[]={1,3,2,1,3,2,1,3,2};
    int i;
    //1.try number of repeat unit test from 1,until the size of array
    for(i=1;i<=sizeof(a)/sizeof(int);i++){
        //2.only try number which is multiple of the size of array,e.g.: n
        int n=sizeof(a)/sizeof(int);
        if(n%i==0){
            //3.check if n is the size of repeat unit
            bool isRepeat=true;
            for(int j=0;j<n;j++){
                for(int r=1;r<i;r++){
                    if(a[j]!=a[j+r*n]){
                        isRepeat=false;
                        break;
                    }
                }
            }
            //4.if the current testing number is repeat unit, break, and the current value of i is the size of repeat unit
            if(isRepeat){
                break;
            }
        }
    }

    //print the result using repeat unit n
    for(int n=0;n<i;n++){
        printf("%d ",a[n]);
    }
};

但它显示 1,3,2,1,3,2,1,3,2 的重复单元是 1 而不是 1,3,2。而且我认为这个解决思路太复杂了,因为它有太多的for循环。有没有更简单的方法或算法来查找数组的重复单元?

最佳答案

似乎你在 if(a[j]!=a[j+r*n]) 中有一个错误

为什么用n来添加呢?不应该是:if(a[j]!=a[j+r*i])

此外,该算法有点慢,另一种解决方法是将每个数字视为字符串中的不同字符,并使用 Knuth Morris-Pratt (KMP) 算法。 ( https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm )

很快会在答案中添加更多信息。

更新:

免责声明:语法和变量可能不完整

KMP 实现:

int F[MAX_N];
int main(void){
    int P[MAX_N], T[MAX_N];
    //1. get input, put it into P array, not coded.
    //....
    //2. insert content of P array to T twice.
    int ptr = 0;
    for(int i = 0;i<2;i++)
        for(int j = 0;j<length_of_p;j++){
            T[ptr++] = P[j];
        }
    //3. get length of repeated unit.
    int repeated = kmp(P, T, 1);
    //4. print the numbers of repeated unit. i.e. done
    cout<<"REPEATED UNIT: ";
    for(int i = 0;i<repeated;i++)
        cout<< P[i] << " ";
    cout<<endl;

    return 0;
}
void kmp_init(int P[]) {
    F[0] = 0;  F[1] = 0;  
    int i = 1, j = 0;
    while(i<P.size()) {
        if (P[i] == P[j])
            F[++i] = ++j;
        else if (j == 0)
            F[++i] = 0;
        else
            j = F[j];
    }
}

int kmp(int P[], int T[], int start) {
    kmp_init(P);
    int i = start, j = 0;
    int n = T.size(), m = P.size();

    while(i-j <= n-m) {
        while(j < m) {
            if (P[j] == T[i]) {
                i++; j++;
            } else break;
        }
        if (j == m) return i-m;
        else if (j == 0) i++;
        j = F[j];
    }
}

关于c++ - 查找数组重复单元的最简单方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37128546/

相关文章:

c++ - 赋值运算符重载c++的返回值

python - 重复数组的每个值两次(numpy)

algorithm - 查找类似 HashMap 的数据结构中作为查询子集的所有键

algorithm - 第 K 条最短路径

c++ - C++虚函数面试题

c++ - 在特定秒数后停止循环的有效方法

arrays - 混淆错误 : Optionality of map's variable changes it from single object to array

python - 第 2 课 : swap elements from arrays

ruby - 选择一个随机选项,其中每个选项被选中的概率不同

javascript - 在 C++ 自定义向导中创建项目模板之前获取现有解决方案名称