字母表可以生成多少个长度为n的字符串?需要一个有效的算法吗

dsekswqp  于 2021-07-12  发布在  Java
关注(0)|答案(2)|浏览(386)

问题是字母表可以组成多少个长度为n的字符串。
条件是:
字母可以在字符串中重复
只有字母表中与字母相邻的字母才能在字符串中相邻放置。例如,如果n=4,字符串可以是d、abab、b、wxyz、xwxw等等。它们不能是e,cdeg,aaaa,因为字母表中只有相邻的字母可以放在一起。
我有n的答案,当:
如果n=3,答案是98
如果n=4,答案是192
如果n=8,答案是2896
如果n=15,答案是342840
如果n=30,答案是9841989098
如果n=40,答案是9329564680878
当n=50时,我需要找到答案。我做的算法在10秒内直到30秒都能得到正确的答案。然而,30岁以后,我认为由于我的算法的递归性质,它一直在运行,我还没有得到答案。
以下是我的java代码:

class Alphabet {

  public int n;

  public long counter = 0;

  public static void main(String[] args) {
    Alphabet a = new Alphabet(15);
    a.run();
  }

  public Alphabet(int n) {
    this.n = n;
  }

  public void run() {

    for (int i = 0; i < 13; i++) {
        this.attach(i, 1);
    }

    System.out.println(this.counter * 2);
  }

  public boolean attach(int letter, int length) {

    if (length == this.n) {
        this.counter++;
        return true;
    }

    if (letter == 0) {
        this.attach(1, length + 1);
        return true;
    }

    if (letter == 25) {
        this.attach(24, length + 1);
        return true;
    }

    this.attach(letter - 1, length + 1);
    this.attach(letter + 1, length + 1);

    return true;
  }
}

有没有更有效的方法得到答案?

atmip9wb

atmip9wb1#

对于每个字母,计算以该字母结尾的长度为1的字符串数。对于所有字母,这是1。
如果你知道以每个字母结尾的n个字母的字符串的数目,那么计算以每个字母结尾的n+1个字母字符串的#就很容易了。根据你的规则,这需要o(字母表大小)时间。反复这样做直到你得到n=n。那就把所有信的数目加起来,你就完了。

sirbozc5

sirbozc52#

如果 x[i][j] 是具有 j 以字母开头的字母 i (从0开始编号),然后 x[i][j] 满足这些递推关系:

x[i][1] = 1
x[0][j] = x[1][j-1]
x[25][j] = x[24][j-1]
x[i][j] = x[i-1][j-1] + x[i+1][j-1]

这为您提供了一种动态编程风格的方法来解决问题(这里是python,因为它使算法更清晰,但将其转换为java没有根本的困难):

def strings(n):
    x = [1] * 26
    for _ in xrange(n-1):
        x = [x[1]] + [x[i-1] + x[i+1] for i in xrange(1, 25)] + [x[24]]
    return sum(x)

print strings(40)

这是一个o(n)(算术运算)解。通过计算26x26矩阵的n次方,可以用o(logn)算术运算来求解它。
A 成为矩阵 a[i][j] 为了 i , j =0..25,其中 a[i][j] = 1 如果 |i-j]=1 否则为0。
然后:

x[][j] = A * (x[][j-1])

(这只是矩阵形式的递推关系)。
然后:

x[][n] = A^(n-1) (x[][1])

由于矩阵的幂可以通过o(logn)算术运算(通过平方乘幂)来计算,所以once可以计算出最终的幂 x[][n] o(logn)时间内的向量。这在实践中并没有太大的帮助,因为数字变得很大,但是如果您需要计算一些k的结果mod k,那么这是一个很好的方法。

相关问题