介绍
因此,我一直在浪费时间来研究后缀排序算法,以手工和代码方式评估新的想法。但是我总是很难记住后缀的类型!能告诉我我的后缀是哪种类型?
最左边是什么?
许多后缀排序算法(SAIS,KA,我自己的daware)将后缀分为不同的类型,以便对其进行排序。有两种基本类型:S型和L型后缀。S型后缀是字典顺序以下(后缀小号比下面后缀和小光伏)L型,如果它是按字典顺序更大(大号 arger)。甲最左边的S型(LMS型)就是:甲S型,其由preceeded后缀L型后缀。
这些LMS类型后缀的特殊之处在于,一旦我们对它们进行了排序,就可以在线性时间内对所有其他后缀进行排序!那不是很棒吗?
挑战
给定一个字符串,假定它以小于该字符串中任何其他字符的特殊字符终止(例如,甚至小于空字节)。为每个后缀输出对应的char类型。
您可以自由选择使用哪种类型的字符哪个,但我更喜欢L, S and *
的L-, S- and LMS-type
,只要它们是所有可打印的(0x20 - 0x7E
)。
例
给定字符串mmiissiissiippi
输出(使用时L, S and *
):
LL*SLL*SLL*SLLL
例如,第一个L
是由于在mmiissiissiippi$
字典上大于miissiissiippi$
($
代表所添加的最小字符)的事实:
L - mmiissiissiippi$ > miissiissiippi$
L - miissiissiippi$ > iissiissiippi$
* - iissiissiippi$ < issiissiippi and preceeded by L
S - issiissiippi$ < ssiissiippi$
L - ssiissiippi$ > siissiippi$
L - siissiippi$ > iissiippi$
* - iissiippi$ < issiippi$ and preceeded by L
S - issiippi$ < ssiippi$
L - ssiippi$ > siippi$
L - siippi$ > iippi$
* - iippi$ < ippi$ and preceeded by L
S - ippi$ < ppi$
L - ppi$ > pi$
L - pi$ > i$
L - i$ > $
其他示例:
"hello world" -> "L*SSL*L*LLL"
"Hello World" -> "SSSSL*SSLLL"
"53Ab§%5qS" -> "L*SSL*SLL"
目标
我不是来惹恼Peter Cordes的(我有一段时间会在stackoverflow上这样做);我很懒,所以这当然是代码高尔夫!以字节为单位的最短答案将获胜。
编辑:字符的顺序由其字节值给出。这意味着比较应该像C一样strcmp
。
Edit2:如注释中所述,每个输入字符应为单个字符。虽然我认为这可以理解为“返回字符串”,但似乎至少有1个答案会返回单个字符的列表。为了不使现有答案无效,我将允许您返回一个单字符列表(或打印时仅产生1个字符的整数)。
线性时间提示:
- 它可以在2个并行的正向迭代中或单个向后的迭代中完成。
- 每个后缀的状态仅取决于前两个字符和第二个字符的类型。
- 反向扫描输入,您可以像这样确定L或S:
$t=$c<=>$d?:$t
(PHP 7),$c
当前字符$d
是前一个和$t
前一个类型。 - 看到我的PHP答案。明天我将颁发赏金。
c++
样式字符串甚至为空字节。将其视为二进制数据。
*
意思
*
表示相应的后缀类型left most s-type
。A S-type suffix that is preceeded by a L-type suffix.
。