Summary of training in the third week

Keywords: C++

1. KMP+Maximum and Minimum Representation

Maximum and Minimum Representation

Maximum and minimum representation is used to solve the problem of string isomorphism. In the time of complexity of $O(n) $, it finds the starting position of the largest (smallest) lexicographic sequence in all isomorphic strings of a string.

Application:

  • Give $n $circular strings to determine how many different strings there are: one by one in the largest (smallest) representation, and then add (Set) to de-duplicate
  • The representation of maximum (minimum) lexicographic order in all isomorphic strings of a cyclic string: the starting position can be obtained by using the maximum (minimum) representation and the output can be obtained.
  • Determine whether two strings are isomorphic: the two strings are represented by the largest (smallest) representation, and then compared character by character

Principle:

Let a string (S\) be the minimal representation of a cyclically isomorphic string of \\(S\\\\\\\\\\\\

The simplest algorithm is to set $i(,\ j (two pointers, ) i (pointing to the position of the smallest representation, J $as the comparison pointer.

Let(i=0), \(j=1), then:

  • If (S[i]>S[j]\), then: (i=j), \(j=i+1)
  • If (S[i]<S[j]\\), then:(j++\)
  • If (S[i]=S[j]\, then set the pointer (k\) from $i $and $j\ (position down comparison until ) S[i]!=S[j], respectively.$
  • If \(S[i+k]>S[j+k]\), then:(i=j), \(j=i+1\)
  • Otherwise, $j++$

Finally, return $i $

As you can see, the naive algorithm moves too few pointers at $S[i]=S[j] (when, ) I $and encounters something like $bbb... When bbbbbba $is such a complex string, the time complexity may degrade to (O(n^2)\. To solve this problem, we improve the algorithm to get the minimum representation of (O(n)\. The core idea is to maintain both (i) and $J pointers at the same time when $S[i]=S[j]$.

Similarly, let(i=0), (j=1), then:

  • If (S[i]>S[j]\), then: (i=j), \(j=i+1)
  • If (S[i]<S[j]\\), then:(j++\)
  • If $S[i]=S[j](), set the pointer \ k(), and compare it downward from \ i (and \) J $, respectively, until \(S[i]!=S[j]\
  • If \(S[i+k]>S[j+k]\, then:(i=i+k)
  • Otherwise(j++)

Final return to the small ones of $i $and $j $

1. Minimum Value Representation

int minmumRepresentation(char *str) //Minimum Representation
{
    int len=strlen(str);
    int i=0;                        //Point to the smallest position of a string
    int j=1;                        //Comparison pointer
    int k=0;            //Moving several times at a time when str[i] and str[j] are equal
    while(i<len&&j<len&&k<len)
    {
        int temp=str[(i+k)%len]-str[(j+k)%len];//Length of comparison value
        if(temp==0)
            k++;
        else
        {
            if(temp>0)              //Maintenance of i
                i=i+k+1;
            else                    //Maintenance of j
                j=j+k+1;
            if(i==j)                //Equal-time comparison pointer backward
                j++;
            k=0;
        }
    }
    return i<j?i:j;                 //Return the smaller one in i and j
}

2. Maximum Representation

int maxmumRepresentation(char *str) //Maximum Representation
{
    int len=strlen(str);
    int i=0;                        //Point to the smallest position of a string
    int j=1;                        //Comparison pointer
    int k=0;            //Moving several times at a time when str[i] and str[j] are equal
    while(i<len&&j<len&&k<len)
    {
        int temp=str[(i+k)%len]-str[(j+k)%len];//Length of comparison value
        if(temp==0)
            k++;
        else
        {
            if(temp>0)              //Maintenance of i
                j=j+k+1;
            else                    //Maintenance of j
                i=i+k+1;
            if(i==j)                //Equal-time comparison pointer backward
                j++;
            k=0;
        }
    }
    return i<j?i:j;                 //Returns the minimum of both
}

Thoughts on HDU-3374 Problem Solving

First, we decide whether it is a cyclic string or not. Then we use the minimum representation and the maximum representation to find the corresponding position. The minimum representation can find a string like a ring, find the beginning of a character, and then the dictionary order of the string is the smallest.

Code:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#define PI acos(-1.0)
#define E 1e-9
#define INF 0x3f3f3f3f
#define LL long long
const int MOD=10007;
const int N=1000000+5;
const int dx[]= {-1,1,0,0};
const int dy[]= {0,0,-1,1};
using namespace std;
int Next[N];
char str[N];
void getNext(char p[])
{
    Next[0]=-1;
    int len=strlen(p);
    int j=0;
    int k=-1;

    while(j<len)
    {
        if(k==-1||p[j]==p[k])
        {
            k++;
            j++;
            Next[j]=k;
        }
        else
        {
            k=Next[k];
        }
    }
}
int minmumRepresentation(char *str) //Minimum Representation
{
    int len=strlen(str);
    int i=0;
    int j=1;
    int k=0;
    while(i<len&&j<len&&k<len)
    {
        int temp=str[(i+k)%len]-str[(j+k)%len];
        if(temp==0)
            k++;
        else
        {
            if(temp>0)
                i=i+k+1;
            else
                j=j+k+1;
            if(i==j)
                j++;
            k=0;
        }
    }
    return i<j?i:j;
}
int maxmumRepresentation(char *str) //Maximum Representation
{
    int len=strlen(str);
    int i=0;
    int j=1;
    int k=0;
    while(i<len&&j<len&&k<len)
    {
        int temp=str[(i+k)%len]-str[(j+k)%len];
        if(temp==0)
            k++;
        else
        {
            if(temp>0)
                j=j+k+1;
            else
                i=i+k+1;
            if(i==j)
                j++;
            k=0;
        }
    }
    return i<j?i:j;
}


int main()
{
    while(scanf("%s",str)!=EOF)
    {
        getNext(str);

        int n=strlen(str);
        int len=n-Next[n];

        int num=1;//Number
        if(n%len==0)
            num=n/len;

        int minn=minmumRepresentation(str);//Minimum representation
        int maxx=maxmumRepresentation(str);//Maximum representation

        printf("%d %d %d %d\n",minn+1,num,maxx+1,num);
    }
    return 0;
}

Two.

Posted by DaveMate on Thu, 12 Sep 2019 04:55:41 -0700