Algorithm 使用后缀数组的最小字典旋转

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,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旋转开始的第一个后缀。

如果您使用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;
}