如何摆脱使用后随机生成的字母?

时间:2014-12-30 21:11:48

标签: java random generator

我目前正在编写一个程序,要求我从字母表中生成随机字母并将其分配给其他字母。 (它是一个加密程序)。问题是,一旦我生成了前几个字母,就会再生成一些字母。

例如, 我想让a = c(随机生成的字母) 但是现在使用了c,我不希望其他25个字母等于c。 所以我不想要b = c 我不知道如何解决这个问题似乎很容易,但我无法做到。

这是我的代码。

for (int i = 0; i<26; i++)
        {
            Random r = new Random();
            cipherArray[i] =(char)(cipherText.charAt(r.nextInt(cipherText.length())));
        }
            return cipherArray;

感谢任何帮助,谢谢。

2 个答案:

答案 0 :(得分:6)

您可以尝试以下操作。

public static void main(final String[] args) {
    List<Character> chars = new ArrayList<>(26);
    for (char c = 'a'; c <= 'z'; c++) {
        chars.add(c);
    }

    Collections.shuffle(chars);
}

它会创建一个字符列表&#39; a&#39;到&#39; z&#39;然后洗牌。

答案 1 :(得分:0)

最快的解决方案是使用Fisher–Yates shuffle;这个SO link中存在java实现。

然而,虽然它被认为是一种非常快速且无偏见的算法,但在你的情况下,使用Fisher-Yates shuffle(显然Collections.shuffle uses it)时的主要问题是它没有&# 39; t保证所有字母都会改变其初始索引。你可能最终会改变几个字母,有时候这些字母不好(想象一下你的元音不会改变;然后它可能很容易解密)。

如果上述问题是一项要求,那么有许多解决方案可以保证每个角色确实发生了变化。我只招募其中一些。

a)最佳方法,使用Sattolo's算法。

 public static void SattoloShuffle(char[] a) {
    int n = a.length;
    Random random = new Random();
    int r;
    char temp;

    for (int i = n; i > 1; i--) {
        // choose index uniformly in [0, i-1)
        r = random.nextInt(i-1);
        temp = a[r];
        a[r] = a[i-1];
        a[i-1] = temp;
    }
}
b)贪婪的方法是迭代运行随机播放,直到你的所有字符从初始位置改变为止。

c)您也可以使用带有a-z字符的数组,然后通过随机选择字符来创建所需的混洗数组,确保相同的字符不会随之改变,例如:

    char[] initialDictionary = new char[] { 'a', 'b', 'c', 'd', 'e', 'f',
            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
            's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
    int n = initialDictionary.length;
    char[] encryptedDictionary = new char[n];

    int i = 0;
    int randomIndex;
    Random random = new Random();
    while (i < n) {
        randomIndex = random.nextInt(n);
        if (randomIndex != i && initialDictionary[randomIndex] != '0') {
            encryptedDictionary[i++] = initialDictionary[randomIndex];
            initialDictionary[randomIndex] = '0'; // use 0 to flag chars already used
        }
    }

d)与上一个解决方案一样,您可以使用列表,但在选择有效字符后,从初始列表中删除此字符。