zoukankan      html  css  js  c++  java
  • sss

    <更新提示>

    <第一次更新>


    <正文>

    最小表示法

    这是一个简单的字符串算法,其解决的问题如下:

    给定一个字符串(S),长度为(n),如果把它的最后一个字符不断放到最前面,会得到(n)个不同的字符串,那么我们称这(n)个字符串是循环同构的。这(n)个字符串中字典序最小的一个,我们就称为(S)的最小表示。

    (For example:)

    (S=abcda,S_1=aabcd,S_2=daabc,S_3=cdaab,S_4=bcdaa)

    其中,(S)的最小表示为(S_1)

    了解了概念以后,我们将介绍一种算法,可以在(O(n))的时间内求出一个字符串的最小表示。

    对于一个环,最朴素的方法就是复制一倍接在原序列后面,这里我们就要用到这种方法:令字符串$$S'i=egin{cases}1 leq ileq n ,S_i <i leq 2n ,S{i-n}end{cases}$$

    然后,利用两个指针(i,j)扫描字符串(S'),其具体方法如下:

    1.初始化(i=1,j=2)
    2.直接向后扫描,比较两个循环同构串(S'(i,i+n-1),S'(j,j+n-1))
    2.(1) 如果扫描了(n)个字符两个串仍然相等,则说明这个字符串只由一个字符构成,任意位置开头都是最小表示
    2.(2) 找到位置(S'_{i+k} != S'_{j+k}),若(S'_{i+k} > S'_{j+k}),则说明位置(j)更优,更新位置(i=i+k+1),若(S'_{i+k} < S'_{j+k}),则说明位置(i)更优,更新位置(j=j+k+1)
    3.若(i>n),则说明位置(j)为最小表示,若(j>n),则说明位置(i)为最小表示

    为什么(S'_{i+k} > S'_{j+k})时,直接将(i)更新为(i+k+1)呢,相信这是最大的一个疑问。

    (Explain:)

    (S'_{i+k} > S'_{j+k})时,显然(S'_i)不是最小表示,因为存在一个更优的最小表示(S'_j)。然而,(S'_{i+p}(1 leq p leq k))均不是最小表示,对于任意的一个(S'_{i+p}),一定也存在一个(S'_{j+p})比它更优,因为它们不断向后比较,同样会在(i+k)处发现有(S'_{i+k} > S'_{j+k})。这样就说明了当一个(i)(i+k)的位置发现不优时,(i+k)以前的也均不优,直接将(i)更新为(i+k+1)即可。

    同理,发现(j)不优时也是一样的。

    (Code:)

    inline void solve(void)
    {
    	int ans;
    	int i=1,j=2,k;
    	while(i<=n&&j<=n)
    	{
    		for(k=0;k<=n&&s[i+k]==s[j+k];k++);
    		if(k==n)break;
    		if(a[i+k]>a[j+k])
    		{
    			i=i+k+1;
    			if(i==j)i++;
    		}
    		else
    		{
    			j=j+k+1;
    			if(i==j)j++;
    		}
    	}
    	ans=min(i,j);
    }
    

    Necklace

    Description

    有一天,袁同学绵了一条价值连城宝石项链,但是,一个严重的问题是,他竟然忘记了项链的主人是谁!在得知此事后,很多人向袁同学发来了很多邮件,都说项链是自己的,要求他归还(显然其中最多只有一个人说了真话)。袁同学要求每个人都写了一段关于自己项链的描述: 项链上的宝石用数字0至9来标示。一个对于项链的表示就是从项链的某个宝石开始,顺指针绕一圈,沿途记下经过的宝石,比如如下项链: 1-2-3-4   

    它的可能的四种表示是0123、1230、2301、3012。

    袁☆同学现在心急如焚,于是他找到了你,希望你能够编一个程序,判断两个给定的描述是否代表同一个项链(注意,项链是不会翻转的)。

    给定两个项链的表示,判断他们是否可能是一条项链。

    Input Format

    输入文件只有两行,每行一个由0至9组成的字符串,描述一个项链的表示(保证项链的长度是相等的)。

    Output Format

    如果两条项链不可能同构,那么输出’No’,否则的话,第一行输出一个’Yes’

    第二行输出该项链的字典序最小的表示。 设L = 项链长度,L <= 1000000。

    Sample Input

    2234342423
    2423223434
    

    Sample Output

    Yes
    2234342423
    

    解析

    这就是一道最小表示法模板题,直接将两个串分别转为最小表示法,再比较是否相同即可。如果相同,直接将最小表示法输出。

    (Code:)

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1000000+20;
    int lena,lenb;
    char a[N*2],b[N*2],Mina[N],Minb[N];
    inline void input(void)
    {
    	scanf("%s",a+1);
    	scanf("%s",b+1);
    	lena=strlen(a+1);
    	lenb=strlen(b+1);
    	for(int i=1;i<=lena;i++)
    		a[lena+i]=a[i];
    	for(int i=1;i<=lenb;i++)
    		b[lenb+i]=b[i];
    }
    inline void solvea(void)
    {
    	int ans;
    	int i=1,j=2,k;
    	while(i<=lena&&j<=lena)
    	{
    		for(k=0;k<=lena&&a[i+k]==a[j+k];k++);
    		if(k==lena)break;
    		if(a[i+k]>a[j+k])
    		{
    			i=i+k+1;
    			if(i==j)i++;
    		}
    		else
    		{
    			j=j+k+1;
    			if(i==j)j++;
    		}
    	}
    	ans=min(i,j);
    	for(int p=1;p<=lena;p++)
    		Mina[p]=a[ans+p-1];
    }
    inline void solveb(void)
    {
    	int ans;
    	int i=1,j=2,k;
    	while(i<=lenb&&j<=lenb)
    	{
    		for(k=0;k<=lenb&&b[i+k]==b[j+k];k++);
    		if(k==lenb)break;
    		if(b[i+k]>b[j+k])
    		{
    			i=i+k+1;
    			if(i==j)i++;
    		}
    		else
    		{
    			j=j+k+1;
    			if(i==j)j++;
    		}
    	}
    	ans=min(i,j);
    	for(int p=1;p<=lenb;p++)
    		Minb[p]=b[ans+p-1];
    }
    int main()
    {
    	input();
    	solvea();
    	solveb();
    	int flag=1;
    	if(lena!=lenb)
    	{
    		printf("No
    ");
    		return 0;
    	}
    	for(int i=1;i<=lena;i++)
    		if(Mina[i]^Minb[i])flag=0;
    	if(!flag)
    	{
    		printf("No
    ");
    		return 0;
    	}
    	else
    	{
    		printf("Yes
    ");
    		for(int i=1;i<=lena;i++)
    			printf("%c",Mina[i]);
    		puts("");
    	}
    	return 0;
    }
    

    <后记>

  • 相关阅读:
    QT类型转换(九种转换)
    QString类的使用(无所不包,极其方便)
    在TreeWidget中增加右键菜单功能 以及TreeWidget的基本用法
    在ubuntu上安装nodejs[开启实时web时代]
    排序和搜索
    new关键字
    Dynamicaly Typed(动态定型), Objective-C Runtime Programming
    图形化机构树
    java-并发之高性能对象
    委托的基本理解与使用
  • 原文地址:https://www.cnblogs.com/Parsnip/p/10574375.html
Copyright © 2011-2022 走看看