Minimum Notation:
In the cyclic array, the array is represented by a sequence with the smallest Lexicographic Order. For example, if A [5] = {5, 1, 3, 2, 4}, the minimum notation is {1, 3, 2, 4, 5 }.
Problem:
Enter two groups of data, both of which are cyclic arrays or ring arrays, to determine whether the two groups of data are consistent?
Set the two arrays to A [] and B [] respectively.
Solution:
Normal Solution: Use two for loops for O (n * n) determination.
KMP method: Copy A to the end of A, and then search for the existence of string B in A. However, the KMP algorithm is too complex and hard to remember. next [] is required.
Minimum notation. Train of Thought 1: Express A and B in minimum notation, and then determine
Minimum notation. Train of Thought 2: Copy A and B to add them to your own end. The specific ideas are as follows:
Step 1: I is the subscript of A, j is the subscript of B, k is the number of steps that I and j move at the same time, initialize I = 0, j = 0, k = 0.
Step 2: If A [I] = B [j], k ++. If A [I]> B [j], I = I + k + 1. If B [j]> A [I], j = j + k + 1. I = I + k + 1 for A [I]> B [j.
This is proved to be true, because A [I] --> A [I + k] is definitely not the smallest representative number, and is added to the [I, I + k] range, if x is the smallest number, B [j + x-I, j + k] <A [x, I + k] is inevitable in B. Conflicts with assumptions.
Step 3: If I <len & j <len & k = len, the two arrays are consistent; otherwise, the two arrays are inconsistent.
Algorithm template:
[Cpp]
/*
Test data:
69867
76896
*/
# Include <iostream>
Const int nmax= 200;
Char str1 [nMax], str2 [nMax];
Char s1 [nMax], s2 [nMax];
Int main ()
{
Freopen ("e: // data.txt", "r", stdin );
While (scanf ("% s", str1, str2 )! = EOF) // here the string is processed
{
Bool flag = 0;
Int len1 = strlen (str1 );
Int len2 = strlen (str2 );
If (len1! = Len2) printf ("NO \ n"); // determines whether the two strings are equal
Memcpy (s1, str1, len1 * sizeof (str1 [0]); // copy str1 to s1 twice, and the result is s1 = str1 + str1
Memcpy (s1 + len1, str1, len1 * sizeof (str1 [0]);
Memcpy (s2, str2, len1 * sizeof (str2 [0]); // similarly s2 = str2 + str2
Memcpy (s2 + len2, str2, len1 * sizeof (str2 [0]);
For (int I = 0, j = 0, k = 0; I <len1 & j <len1 & k <len1 ;)
{
If (s1 [I + k] = s2 [j + k]) ++ k;
Else if (s1 [I + k]> s2 [I + k]) I = I + k + 1, k = 0;
Else j = j + k + 1, k = 0;
If (k = len1)
{
Flag = 1;
Break;
}
}
Printf ("% s \ n", flag = 1? "YES": "NO ");
}
}
// Another use of the least representation, directly returning the minimum representation in the array s []
Int getMin (char s [], int len) // s [] can also be defined as another type
{
Int I = 0, // I, j Initialization is different
J = 1,
K = 0;
While (I <len & j <len & k <len) // compare yourself with yourself. A [], B [] are arrays of s [], using I, j corresponds to different subscripts.
{
Int t = s [(I + k) % len]-s [(j + k) % len]; // This is equivalent to concatenating two character arrays s.
If (! T) // The two arrays are equal.
++ K;
Else
{
If (t> 0)
I + = k + 1;
Else
J + = k + 1;
If (I = j) // The purpose of the function is to return the minimum number of representations. You only need to keep the smaller one of I and j. Therefore, when j = j occurs, I ++ or j ++, continue matching
I ++;
}
K = 0;
}
Return I <j? I: j; // return the smaller I, j.
}
Author: lhshaoren