Algorithm 使用后缀数组的最小字典旋转
所以我计算了后缀数组SA,SA[]={13,6,9,2,11,4,7,0,10,3,12,5,8,1} 此外,我还计算了LCPs b/w every后缀[尽管我不确定在这个问题中是否需要它] 现在如何继续。如何使用SA获得所需的结果? 用一个很小的例子来解释将会非常有效Algorithm 使用后缀数组的最小字典旋转,algorithm,suffix-array,Algorithm,Suffix Array,所以我计算了后缀数组SA,SA[]={13,6,9,2,11,4,7,0,10,3,12,5,8,1} 此外,我还计算了LCPs b/w every后缀[尽管我不确定在这个问题中是否需要它] 现在如何继续。如何使用SA获得所需的结果? 用一个很小的例子来解释将会非常有效 谢谢 似乎应该使用SA中的第一个后缀,该后缀的索引介于0和长度(S)-1之间 一些解释:S的所有旋转都是从0到长度(S)-1之间的位置开始的S后缀。后缀数组保持后缀按字典顺序排列,因此您只需选择从S旋转开始的第一个后缀。如果您使
谢谢 似乎应该使用SA中的第一个后缀,该后缀的索引介于0和长度(S)-1之间 一些解释:S的所有旋转都是从0到长度(S)-1之间的位置开始的S后缀。后缀数组保持后缀按字典顺序排列,因此您只需选择从S旋转开始的第一个后缀。如果您使用O(n log n)算法(按第一个字母排序,然后按前两个字母排序,然后按前四个字母排序,…),您可以稍微修改后缀数组 不要对字符串的后缀排序,但它是循环旋转的。这应该是对算法的微小修改。A然后你会直接得到想要的结果
如果您仍然想使用您的方法,那么只需使用第一个介于0和N之间的索引。谢谢大家。vkorchagin和usamec的答案对大多数测试用例都是正确的,但它们对以下测试用例不起作用(S=“baabaa”) S=巴巴拉; S'=咩咩咩
For example:
S=alabala
S'=alabalaalabala
Suffix No. Index Suffixes
0 13 a
1 6 aalabala
2 9 abala
3 2 abalaalabala
4 11 ala
5 4 alaalabala
6 7 alabala
7 0 alabalaalabala
8 10 bala
9 3 balaalabala
10 12 la
11 5 laalabala
12 8 labala
13 1 labalaalabala
对于上面的测试用例,使用索引在0到S.length()之间的第一个后缀不起作用。如果我这样做,那么结果是4,但正确答案是1
所以我稍微修改了答案
这就是我所做的,或在上述答案中添加/修改了一个附加条件:
(1) 我使用了索引介于0到S之间的第一个后缀。length()-1
假设它的索引是:=ExpectedIdx
在上面的示例中,expectedx=4
(2) .现在,预期的dx可能是答案,也可能不是答案。原因是后缀数组中的下一个后缀可能会产生相同的答案
例如:
以起始索引为4(ExpectedIdx)的后缀aabaab
aa.,我们得到aabaab
作为最小词汇旋转字符串
取下一个后缀,aabaab
aabaa
我们还得到aabaab
作为最小的Lexograhic旋转字符串
但是前者需要4的移位,而后者需要1的移位。所以正确答案是1,而不是4。
因此,我使用最长公共前缀(LCP)的概念来检查相似性,并最终被接受
编辑::这是伪代码-
Suffix| Suffix | Suffixes
Index | Length |
11 1 a
10 2 aa
7 5 aabaa
4 8 aabaabaa
1 11 aabaabaabaa
8 4 abaa
5 7 abaabaa
2 10 abaabaabaa
9 3 baa
6 6 baabaa
3 9 baabaabaa
0 12 baabaabaabaa
int expecteddx,ExpectedSuffixNumber,ExpectedSuffixLength;
对于(int i=0;在本例中,我必须得到小于S大小的第一个数字6。您在问题“确定最小字典旋转,如果有更多,则选择旋转量最小的一个”?不。无论如何,您不需要LCP。您只需要在结束标记之前使用普通字符(因此“aa”在“a”之前)(等等)@usamec::哦,是的,该死的,我没有提到这个问题中的条件..抱歉,无论如何,答案对我来说是有效的,我自己在你的答案中添加了一个额外的条件,以使我的答案被接受..这个解决方案是错误的!例如,对于字符串CABA,最小的后缀是A,然后添加单词的其余部分来完成我们的旋转t ACAB,但最小的词典轮换是ABAC!前面的注释不正确,答案几乎正确,前提是创建附加到自身的文本后缀数组,并且仅从后缀中提取第一个长度字符。最小索引介于0和0之间
Suffix| Suffix | Suffixes
Index | Length |
11 1 a
10 2 aa
7 5 aabaa
4 8 aabaabaa
1 11 aabaabaabaa
8 4 abaa
5 7 abaabaa
2 10 abaabaabaa
9 3 baa
6 6 baabaa
3 9 baabaabaa
0 12 baabaabaabaa
int ExpectedIdx,ExpectedSuffixNumber,ExpectedSuffixLength;
for(int i=0;i<strlen(str);++i)//str = Length of S'
{
suffixsize=strlen(str)-SA[i];
if(suffixsize>(Len/2))//Len/2:=Size of S
{
ExpectedIdx=SA[i];
ExpectedSuffixNumber=i;
ExpectedSuffixLength=suffixsize;
break;
}
}
//Now this ExpectediDx may or may not be the correct answer.
int finalans=ExpectedIdx;//Lets assume initially that ExpectedIdx is a correct/final answer.
for(int i=(ExpectedSuffixNumber+1);i<Len;++i)//Check the Next Suffix
{
if(LCP[i]>Len/2)//LCP[i]=Lingest common prefix of adjacent prefixes in a suffix Array.
{
if(SA[i]>finalans)
{
finalans=SA[i];
}
}
else
break;
}