What is the best way to find the period of a (repeating) list in Mathematica?

前端 未结 9 1203
没有蜡笔的小新
没有蜡笔的小新 2021-01-01 15:12

What is the best way to find the period in a repeating list?

For example:

a = {4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2}

has repeat

相关标签:
9条回答
  • 2021-01-01 16:11

    Does this work for you?

    period[a_] := 
       Quiet[Check[
          First[Cases[
             Table[
                {k, Equal @@ Partition[a, k]}, 
                {k, Floor[Length[a]/2]}], 
             {k_, True} :> k
             ]], 
          $Failed]]
    

    Strictly speaking, this will fail for things like

    a = {1, 2, 3, 1, 2, 3, 1, 2, 3, 4, 5}
    

    although this can be fixed by using something like:

    (Equal @@ Partition[a, k]) && (Equal @@ Partition[Reverse[a], k])
    

    (probably computing Reverse[a] just once ahead of time.)

    0 讨论(0)
  • 2021-01-01 16:11

    I propose this. It borrows from both Verbeia and Brett's answers.

    Do[
      If[MatchQ @@ Equal @@ Partition[#, i, i, 1, _], Return @@ i],
      {i, #[[ 2 ;; Floor[Length@#/2] ]] ~Position~ First@#}
    ] /. Null -> $Failed &
    

    It is not quite as efficient as Vebeia's function on long periods, but it is faster on short ones, and it is simpler as well.

    0 讨论(0)
  • 2021-01-01 16:11
    #include <iostream>
    #include <vector>
    using namespace std;
    
    
    int period(vector<int> v)
    {
        int p=0; // period 0
    
        for(int i=p+1; i<v.size(); i++)
        {
    
            if(v[i] == v[0])
            {
                p=i; // new potential period
    
    
                bool periodical=true;
                for(int i=0; i<v.size()-p; i++)
                {
                    if(v[i]!=v[i+p])
                    {
                        periodical=false;
                        break;
                    }
                }
                if(periodical) return p;
    
    
                i=p; // try to find new period
            }
        }
    
        return 0; // no period
    
    }
    
    
    int main()
    {
    
        vector<int> v3{1,2,3,1,2,3,1,2,3};
        cout<<"Period is :\t"<<period(v3)<<endl;
    
    
        vector<int> v0{1,2,3,1,2,3,1,9,6};
        cout<<"Period is :\t"<<period(v0)<<endl;
    
        vector<int> v1{1,2,1,1,7,1,2,1,1,7,1,2,1,1};
        cout<<"Period is :\t"<<period(v1)<<endl;
        return 0;
    }
    
    0 讨论(0)
提交回复
热议问题