「学习笔记」字符串最小表示法 (简)

「学习笔记」字符串最小表示法 (简)

【模板】最小表示法

过程

维护三个指针 \(i,j,k\).

\(i,j\) 表示目前正在进行比较的两个起始位置, 保证 \(i<j\), \(k\) 表示这两个起始位置对应的串的 \(LCP\) 长度.

每次对 \(k++\) , 然后根据 \(s[i+k]\)\(s[j+k]\) 的大小关系调整 \(i,j\) 的位置.

\(s[i+k]<s[j+k]\), 那么在区间 \([j,j+k]\) 范围内的起始位置 \(x\) 肯定不是最优解, 因为 \(i+x-j\) 一定比它优, 所以让 \(j=j+k+1,k=0\).

\(s[i+k] > s[j+k]\), 按照上面的操作, 在区间 \((i,j)\) 范围内的其实位置已经被排除了, 所以直接让 \(i=j,j++,k=0\).

\(s[i+k] = s[j+k]\), 则判断 \(k\) 是否等于 \(n\), 若等于 \(n\) 则输出 \(i\).

算法过程中若 \(j>n\), 则同样输出 \(i\).


代码

void Run(){                // 字符串从 0 开始
	int i=0,j=1,k=0;
	while(i<n&&j<n&&k<n){
		if(a[(i+k)%n]>a[(j+k)%n]){
			i=i+k+1,k=0;
			if(i<j) i=j,j++;
			else swap(i,j);
		}
		else if(a[(i+k)%n]<a[(j+k)%n]) j=j+k+1,k=0;
		else k++;
		if(i==j) j++;
	}
}
posted @ 2020-06-17 11:58  BruceW  阅读(155)  评论(0编辑  收藏  举报