找到数组重复单元的最简单方法是什么
What is simplest way to find repeat unit of array?
例如,的重复单元
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]
- 如果当前测试数是重复单元,则break,并且i的当前值是重复单元的大小
我尝试将其转换为代码:
#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,3,2的重复单元是1,而不是1,3,2。我认为这个求解思想太复杂了,因为它有太多的循环。有没有更简单的方法或算法来找到数组的重复单元?
似乎您在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];
}
}
这里的错误在于,当i为1时,您首先检查大小写,当然,它将被检测为重复单元。那是因为
for(int r=1;r<i;r++)
如果i=1
(您的第一个病例),将立即断开。
如果你确信你的数字在0到9之间(即只有一个数字),并且你想要一个"简单"的解决方案(正如你在标题中所说),你可以使用数字构建一个字符串,将字符串拆分为子字符串,并检查它们是否都相等。
#include <stdio.h>
#include <string.h>
int main(){
int nums[]={1,3,2,1,3,2,1,3,2};
char initial_string[255];
char string_list[255][255];
int i, j, k, l;
int found = 0;
memset(initial_string, 0, 255);
for(i=0; i < sizeof(nums)/sizeof(int); i++) {
initial_string[i] = '0' + nums[i];
}
int n = sizeof(nums)/sizeof(int);
memset(string_list, 0, 255*255);
for(i = 1; i <= n; i++) {
if (n%i == 0) {
int count = (int)n/i;
for (k = 0, j = 0; k < n; k+=i, j++) {
strncpy(string_list[j], &initial_string[k], i);
}
found = 1;
for (k = 0; k < count; k++) {
if (strcmp(string_list[0], string_list[k])) {
// Different strings!
found = 0;
break;
}
}
}
if (found) {
break;
}
}
printf("Repeat unit: %dn", i);
}
请注意,此代码是NOT最优的,有几点需要改进,请将其作为一个总体想法。
您可以在此处使用STL集函数。像这样,
int main()
{
set< int > s;
s.insert(1);
s.insert(3);
s.insert(2);
s.insert(1);
s.insert(3);
s.insert(2);
s.insert(1);
s.insert(3);
s.insert(2);
set< int > :: iterator it;
for(it = s.begin(); it != s.end(); it++) {
cout << *it << endl;
}
它将打印不同的元素,因此您可以找到任何数组的重复单元。快乐编码!
相关文章:
- 当无法使用模板和宏时,生成类型变体C++代码的最简单方法是什么?
- 在OSX上使用CMake将Adobe的XMP工具包构建为共享库的最简单方法是什么?
- 通过比较C++中的行在 txt 文件中搜索的最简单方法是什么?
- 将时间戳打印到流的最简单方法
- 在C++中创建文件夹选取器对话框的最简单方法是什么?
- boost::variant - 对变体应用算术的最简单方法
- 创建可以遍历 std::map 值的通用模板迭代器的最简单方法是什么?
- 在C++中将算术类型转换为 std::array 的最简单方法<uint8_t>
- C++-将ASCII字符数组中可能的数值转换为字符的最简单方法
- 从 txt 文件中读取数据的最简单方法
- 根据浮点符号对浮点进行舍入的最简单方法是什么
- 对于我扩展此程序来计算最高10x10矩阵的倒数的最简单方法是什么
- C++98 中获取并继续调用当前类不知道的类方法的最简单方法是什么?
- 编写要在 Python 中使用的并行 C/C++ 模块的最简单方法
- 开放式颜色多边形表面的最简单方法
- 确定代码中当前程序集是否为 32/64 位的最简单方法
- 将unique_ptr存储在堆上的最简单方法是什么
- 使用 C# 获取 OpenGL 版本的最简单方法
- 在自定义 C/C++ 程序中获取 PPP0 接口 Tx/Rx 字节的最简单方法是什么?
- 为depth_first_search定义颜色图的最简单方法