在数组中查找重复图案

时间:2018-10-11 16:10:44

标签: c++

在一个以1,9,9,0,9,7,5,1开头的数组中,第四个数字之后的每个数字是前4个数字之和的最后一位数字(1 + 9 + 9 + 0 = 19,下一位数字是9),计算何时在阵列中再次发生模式1,9,9,0。 我在查找模式时遇到问题,这是我当前的代码。

#include <iostream>
using namespace std;

int main()
{
    int n[500];
    n[0]=1,n[1]=9,n[2]=9,n[3]=0,n[4]=9;
    int suma,i=5,b=0,c=0;
do
    {
        b=i;
        suma=0;
        suma=suma+(n[i-1]+n[i-2]+n[i-3]+n[i-4]); 
        n[i]=suma%10;
        cout << n[i] << "::" << endl;
        if(n[i-1]==0 && n[i-2]==9 && n[i-3]==9 && n[i-4]==1)
        {
            cout << "break"; break;
        }
        i++;
    }while(i!=1000);
    return 0;
}

2 个答案:

答案 0 :(得分:1)

我在这里看到的一个问题是

您没有足够的循环来获取序列。 为此,您需要更大的数组。

当您声明较小的数组并循环更多时,由于数组超出了访问范围,您将调用未定义的行为。

解决方案:

要么声明更大的数组并进行足够的循环

如评论部分所述,重复可以随时发生 因此,您无法拥有预定义长度的数组,因为您不知道将发生多少次重复。

因此,您只需要长度为5的数组,并使用%循环的while(1)运算符即可解决问题。

提示是您需要在第4个元素之后存储和,因此(i+4)%5将为您提供需要存储和的位置,并且您可以同时访问1st,2nd,3rd4th元素方式

(i+0)%5 --> will get you the first element
(i+1)%5 --> will get you the second element
(i+2)%5 --> will get you the third element
(i+3)%5 --> will get you the fourth element

完整的代码可能如下所示。

#include <iostream>
using namespace std;

int main()
{
    int n[5];
    n[0]=1,n[1]=9,n[2]=9,n[3]=0;
    int suma,i=0;
    do
    {
        suma=0;
        suma=suma+(n[(i+0)%5]+n[(i+1)%5]+n[(i+2)%5]+n[(i+3)%5]); 
        n[(i+4)%5]=suma%10;
        cout << n[(i+0)%5] <<n[(i+1)%5]<<n[(i+2)%5]<<n[(i+3)%5]<<n[(i+4)%5]<< "::" << endl;
        if(n[(i+0)%5]==1 && n[(i+1)%5]==9 && n[(i+2)%5]==9 && n[(i+3)%5]==0 && i > 0)
        {
            cout << "break"; break;
        }
        i++;
    }while(1);
    return 0;
}

或 如您所见,上面的代码不太可读。

您可以使用下面的lambda使其可读。

#include <iostream>
using namespace std;

int main()
{
    int n[5];
    n[0]=1,n[1]=9,n[2]=9,n[3]=0;
    int suma,i=0;
    do
    {
        auto p = [&](int offset) -> int& { return n[(i+offset)%5]; };
        suma=p(0)+p(1)+p(2)+p(3); 
        p(4)=suma%10;        
        if(p(0)==1 && p(1)==9 && p(2)==9 && p(3)==0 && i >0)
        {
            cout << "break \n"; break;
        }
        i++;
    }while(1);
    std::cout << i;
    return 0;
}

并使用-std=gnu++1y标志进行编译。

  

为了您的信息重复发生在第1560次迭代

答案 1 :(得分:1)

代码的唯一问题是您无法访问数组。您的数组是

int n[500];

然后循环结束

}while(i!=1000);

如果您修复了it does find a solution!

无论如何,我认为这是一个有趣的问题,实际上是在意识到您的代码已经正确(除了越界)之前写了这个:

#include <iostream>
#include <array>

using quad = std::array<int,4>;

int get_next_number(const quad& q) { return (q[0]+q[1]+q[2]+q[3])%10; }
quad get_next(const quad& q) { return { q[1],q[2],q[3],get_next_number(q) }; }

int main() {
    quad init{1,9,9,0};
    int counter = 0;
    quad current = get_next(init);
    while (init != current) { 
        ++counter;
        current = get_next(current);
    }   
    std::cout << counter;
}

当您需要的只是最后四个条目时,您无需存储所有数字。通过使用仅保留最后4个数字的std::array,比较也更容易理解。

请注意,@ kiran Biradar的解决方案效率更高,因为上面我不必要地移动每一步中的所有数字,而他的代码仅在每一步中分配一个元素。