我目前正在编写一个程序,要求我从字母表中生成随机字母并将其分配给其他字母。 (它是一个加密程序)。问题是,一旦我生成了前几个字母,就会再生成一些字母。
例如, 我想让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;
感谢任何帮助,谢谢。
答案 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)与上一个解决方案一样,您可以使用列表,但在选择有效字符后,从初始列表中删除此字符。