zoukankan      html  css  js  c++  java
  • String Problem

    题目大意:有一个字符串长度为N的字符串,这个字符串可以扩展出N个字符串,并且按照顺序编号,比如串 
    SKYLONG
    SKYLONG 1 
    KYLONGS 2 
    YLONGSK 3 
    LONGSKY 4 
    ONGSKYL 5 
    NGSKYLO 6 
    GSKYLON 7
    下面这7个都是原串的扩展(循环位移),现在需要求出来字典序最小的和字典序最大的那个串的标号。
     
    输出说明:最小字典序的编号,最小字典序个数,最大字典序编号,最大字典序个数。
     
    分析:以前也遇到过类似的求最小字典序的问题,不过当时不会,今天研究了一下发现是有个方法来专门处理这种问题的,就是最大最小表示
    ,这种方法采用两个指针,表示两个串的开头,如果开头不同直接让字典序大的后移,如果开头相同那么就使用一个计数长度k来往后移动,知道发现s[i+k] != s[j+k] 当然如果k==N那么这两个串都是最小的字典序了,否则,就让值大的那个指针往后移动,直到有指针超过N为止。
     
    下面是代码:
    ==========================================================================================================
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<stdlib.h>
    using namespace std;
    
    const int MAXN = 1e6+7;
    
    char s[MAXN<<1], s1[MAXN];
    int Next[MAXN];
    
    void GetNext(char s[], int N)
    {
        int i=0, j=-1;
        Next[0] = -1;
    
        while(i < N)
        {
            if(j==-1 || s[i]==s[j])
                Next[++i] = ++j;
            else
                j = Next[j];
        }
    }
    int GetMin(char s[], int N)
    {///求最小的字典序的开始
        int i=0, j=1;
    
        while(i<N && j<N)
        {
            int k = 0;
    
            while(s[i+k] == s[j+k] && k<N)
                k++;
    
            if(k == N)break;
    
            if(s[i+k] < s[j+k])
            {
                if(j+k > i)
                    j = j+k+1;
                else
                    j = i+1;
            }
            else
            {
                if(i+k > j)
                    i = i+k+1;
                else
                    i = j+1;
            }
        }
    
        return min(i, j);
    }
    int GetMax(char s[], int N)
    {///求最大的字典序的开始
        int i=0, j=1;
    
        while(i<N && j<N)
        {
            int k = 0;
    
            while(s[i+k] == s[j+k])
                k++;
    
            if(k == N)break;
    
            if(s[i+k] > s[j+k])
            {
                if(j+k > i)
                    j = j+k+1;
                else
                    j = i+1;
            }
            else
            {
                if(i+k > j)
                    i = i+k+1;
                else
                    i = j+1;
            }
        }
    
        return min(i, j);
    }
    
    int main()
    {
        while(scanf("%s", s1) != EOF)
        {
            int N = strlen(s1);
    
            strcpy(s, s1);
            strcat(s, s1);
    
            GetNext(s, N);
            int circle = N-Next[N], times=1;
    
            if(N % circle == 0)
                times = N / circle;
    
            printf("%d %d %d %d
    ", GetMin(s, N)+1, times, GetMax(s, N)+1, times);
        }
    
        return 0;
    }
     
  • 相关阅读:
    winform控件库二次开发yy
    Oracle数据库表死锁和解锁
    集合去重筛选
    linux手动生成core dump
    HandlerSocket简介以及php使用handlersocket
    使用truss、strace或ltrace诊断软件的“疑难杂症”
    Sqlserver 2012 导出表数据为SQL脚本
    MySQL的索引为什么使用B+Tree
    计算机体系
    docker使用
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4742391.html
Copyright © 2011-2022 走看看