【问题标题】:Fill array with the alphabet using rand function in C使用C中的rand函数用字母填充数组
【发布时间】:2014-11-29 17:16:39
【问题描述】:

我正在编写一个编码和一个解码程序,所以我需要使用 rand 创建一个字母数组,以便对其进行洗牌。我下面的代码导致字母重复。如何使用 rand 函数让 26 个字母中的每一个都出现? 我确实尝试过创建一个使用过的字符数组,但这导致字符超出了 'a' - 'z' 范围,主要是空格。

int main(int argc, char *argv[]) {
    int key, currch, i;
    char plain[] = "abcdefghijklmnopqrstuvwxyz";
    char coded[26];
    key = atoi(argv[1]);
    srand((unsigned)key);

    for(i=0; i<26; i++) {
            coded[i] = 'a' + rand() % 26;
    }
 // testing to see what is in the array
    i=0; 
    while(i<26) {
            printf("%c ", coded[i]);
            i++;
    }
}

使用 33 作为种子时的输出是

z h w p b i h x c q u m a v u v f u k u j j d s y g

如你所见,有重复的(u、v、j)

感谢您的任何反馈!

【问题讨论】:

  • 首先以已知的顺序(例如明显的顺序)将每个字母放入数组一次,然后通过重复选择要交换的随机元素对来随机打乱数组。请注意,要获得无偏见的随机播放,您需要依次考虑每个元素,然后选择在相同位置或右侧的另一个元素进行交换。

标签: c arrays random


【解决方案1】:

算法错误,您得到的是随机值,但没有对数组进行洗牌。 plain 根本没有在您的代码中使用。

一种有效的洗牌算法是Fisher–Yates shuffle,也称为 Knuth 洗牌。伪代码为:

for i from n − 1 downto 1 do
   j ← random integer with 0 ≤ j ≤ i
   exchange a[j] and a[i]

【讨论】:

  • Plain 是一个单独的数组,用于与我的问题无关的不同目的。 coded[] 是洗牌数组所在的位置。两个回复都有帮助。谢谢!
猜你喜欢
  • 2018-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-18
  • 2014-03-28
  • 1970-01-01
相关资源
最近更新 更多