【问题标题】:how to shuffle char "abcdefghijklmnopqrstuvwxyz" without repeating如何在不重复的情况下随机播放字符“abcdefghijklmnopqrstuvwxyz”
【发布时间】:2012-07-15 08:56:06
【问题描述】:
const char chars[] = "abcdef ...."; 
char result[...];
memcpy(result, chars, sizeof(chars)); 
for (unsigned i = 0; i < (sizeof(chars)-1); ++i) {
    unsigned j = rand() % sizeof(chars);
    char tmp = result[j];
    result[j] = result[i];
    result[i] = tmp;
} 

将结果写入文本文件时出现问题。

【问题讨论】:

    标签: c++ random shuffle


    【解决方案1】:

    在 C++ 中“如何洗牌”的答案是使用标准库的洗牌算法之一。一种简单的方法是将其放入std::string,然后使用std::random_shuffle

    std::string s = "abcdef ...." ;
    std::random_shuffle(s.begin(), s.end());
    

    你也可以用数组来做:

    char letters[] = {'a', 'b', ..... };
    std::random_shuffle(letters, letters+26);
    

    【讨论】:

    • 使用这种方法,洗牌是否固定?我希望程序无需重复即可生成不同的改组。
    • @user1526669 它将被修复,但您可以处理用于生成随机数的种子,因此可以在每次运行程序时使用日期或其他内容来生成不同的密钥。文档here 应该提供更多线索。
    【解决方案2】:

    给你:Fisher–Yates shuffle

    还有一个C++ implementation

    【讨论】:

      【解决方案3】:

      您的问题是字符值 0 未映射到 A。相反,将打印为 A 的字符等于 65。如果您需要,可以查看完整的表 here

      无论如何,代码解决方案很简单。 而不是

      cout<<letter[i]<<" ";
      

      你可以这样做:

      cout<<letter[i]+'A'-1<<" ";
      

      (-1 是因为您将字母编号从 1 到 26 而不是 0 到 25)。

      【讨论】:

      • 是的,没有 +1 会更整洁,这里完全没有必要。
      • 我试过你的方法,它没有给我有趣的角色,但它给了我数字 65-90 我如何将它们显示为字母?
      • @user1526669:没有 -1 它将起作用。目前,它将所有内容都转换为整数(字符提升为整数)。所以要么删除 +-1,要么做 cout
      【解决方案4】:
      const char chars[] = "abcdef ...."; 
      char result[...];
      memcpy(result, chars, sizeof(chars)); 
      for (unsigned i = 0; i < (sizeof(chars)-1); ++i) {
          unsigned j = rand() % sizeof(chars);
          char tmp = result[j];
          result[j] = result[i];
          result[i] = tmp;
      }
      

      如果您使用 STL,则首选 std::random_shuffle。

      【讨论】:

        猜你喜欢
        • 2012-10-23
        • 2011-03-20
        • 2019-10-12
        • 1970-01-01
        • 2015-02-20
        • 2017-09-13
        • 1970-01-01
        • 1970-01-01
        • 2020-09-01
        相关资源
        最近更新 更多