简体   繁体   English

在数组中查找重复图案

[英]Find a repeating pattern in an array

In an array that starts with 1,9,9,0,9,7,5,1 each number after the 4th one is the last digit of the sum of the previous 4 numbers ( 1 + 9 + 9 + 0 = 19, 9 is the next digit), calculate when will the pattern 1,9,9,0 happen again in the array. 在以1,9,9,0,9,7,5,1开头的数组中,第四个数字之后的每个数字是前4个数字之和的最后一位数字(1 + 9 + 9 + 0 = 19, 9是下一位数字),计算何时在阵列中再次发生模式1,9,9,0。 I'm having problems finding the pattern, here is my current code. 我在查找模式时遇到问题,这是我当前的代码。

#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;
}

One problem I see here is. 我在这里看到的一个问题是。

You are not looping enough to get the sequence. 您循环不足以获取序列。 For that you need larger array. 为此,您需要更大的数组。

When you declare smaller array and loop more than that you invoke undefined behavior because of array out of bound access. 当声明较小的数组并循环更多时,由于数组超出了访问范围,您将调用未定义的行为。

Solution: 解:

Either you declare larger array and loop enough 您可以声明更大的数组并足够循环

Or 要么

As told in the comment section repetition can occur any time hence you cannot have array with predefined length as you don't know how many repetition will occur. 如评论部分所述,重复可以随时发生,因此您不能拥有预定义长度的数组,因为您不知道会发生多少次重复。

Hence you only need array of length 5 and use % operator with while(1) loop to solve the problem . 因此,您只需要长度为5的数组,并将%运算符与while(1)循环一起使用即可解决问题。

The clue is you need to store the sum after the 4th element hence (i+4)%5 will get you the place where sum need to be stored and you access the 1st,2nd,3rd and 4th element same way 提示是您需要将和存储在第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

Complete code might look like below. 完整的代码如下所示。

#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;
}

or As you see the above code is less readable. 或如您所见,上面的代码可读性较差。

You can make it readable by using a lambda as below. 您可以使用下面的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;
}

and compile using -std=gnu++1y flag. 并使用-std=gnu++1y标志进行编译。

For your information repetition is occurring at 1560th iteration 为了您的信息,重复发生在第1560次迭代中

The only problem with your code is that you access the array out of bounds. 代码的唯一问题是您无法访问数组。 Your array is 你的数组是

int n[500];

and then the loop goes till 然后循环直到

}while(i!=1000);

If you fix that it does find a solution! 如果您修复它,确实找到了解决方案!

Anyhow, I thought it is an interesting problem and actually wrote this before realizing that your code is already correct (apart from the out-of-bounds): 无论如何,我认为这是一个有趣的问题,并在意识到您的代码已经正确(除了超出范围)之前实际编写了此代码:

#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;
}

You dont need to store all numbers when all you need at any time are the last four entries. 当您需要的全部为最后四个条目时,您无需存储所有数字。 By using an std::array that holds only the last 4 numbers also the comparison is more readable. 通过使用仅保存最后4个数字的std::array ,比较也更易读。

Note that @kiran Biradar s solution is more efficient, because above I unecessarily do shift all the numbers in each step while his code just assigns one element in each step. 请注意,@ kiran Biradar的解决方案效率更高,因为在上面,我不必要地移动每一步中的所有数字,而他的代码仅在每一步中分配一个元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM