【问题标题】:Create A Random String with constraints in C++ [closed]在 C++ 中创建带有约束的随机字符串 [关闭]
【发布时间】:2013-11-29 00:52:30
【问题描述】:

我想创建一个长度为 m*j 的随机字符串,例如 m=4,j=3。 我这样做了

static const char alphanum[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
return alphanum[rand() % stringLength]    

我保留了 stringlength=3 以便返回值仅由长度为 20 的随机顺序的前三个字母(A、B、C)组成

我现在要做的是有一个随机字符串,其中 A 只有 3 次 B 只有 4 次,C 只有 3 次。 如何应用这些约束? 计数器?

嗨, 我做了类似于答案中建议的事情。这是代码

static const char alphanum[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
//Function which generates a random character
char GetRandom(int Position){
    return alphanum[rand() % Position];
}
//******************************************************************************
//                          MAIN
//******************************************************************************
int main()
{
    //Assuming a 3 machines 3 jobs scenario. So chromosome
    int Jobs=4;
    int Machines=3;
    int ChromLength=Jobs*Machines;
    int StringLength=Jobs;
    int Counter[Jobs],i;
    char C;
    char Chromosome[(ChromLength-1)];
    //Seeding
    srand(time(0));
    //Init array
    for(int Cnt=0;Cnt<Jobs;Cnt++)
        Counter[Cnt]=0;
    //Test
    //Fill the array
    for(i=0;i<ChromLength;)
    {
        //Get the Character
        C=GetRandom(StringLength);
        cout<<"Char:"<<C<<endl;
        //Check which character is returend
        for(int j=0;j<StringLength;j++)
        {
            if(C==alphanum[j])
            {
                Counter[j]++;
                cout<<"I am in J "<<j<<" Char:"<<C<<endl;
                if(Counter[j]==Jobs)
                    break;
                else
                {
                    Chromosome[i]=C;
                    cout<<"I:"<<i<<endl;
                    i++;
                }
            }
        }
    }
    cout<<Chromosome;

    return 0;
}

但输出中有一些尾随字符无法理解它们是什么 这是一个截图

【问题讨论】:

  • 为什么要添加 C 和 OOP 标签?
  • 字符串末尾有垃圾的原因是您没有 NULL 终止它。
  • 谢谢@RetiredNinja 我现在得到了正确的结果:-)

标签: c++ random


【解决方案1】:

我最近需要做类似的事情,所以我想出了这个:

#include <iostream>
#include <random>
#include <vector>
#include <cctype>
#include <algorithm>

首先我们有一个返回随机字符的函数。

unsigned seed1 = std::chrono::system_clock::now().time_since_epoch().count();
/* or try this:
std::random_device rd; 
auto seed1= rd();
*/
std::minstd_rand0 g1 (seed1);
static const std::string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
std::uniform_int_distribution<int> dist(0, alphabet.size()-1);

char get_random_char() {
    return alphabet[dist(g1)];
}

然后此函数获取随机字符并拒绝那些与谓词不匹配的字符。当所有字符都满足谓词时,循环停止。

    template <class Pred>
    std::string generate_string(int length, Pred pred) {
        int index = 0;
        std::string final = "";
        while (true) {
           char current = get_random_char();
           if (!pred(index, current)) continue;

           final += current;

           index++;
           if (index >= length) break;
        }
        return final;
    }

这里的谓词是作为 lambda 传入的。为简单起见,我计算了 A、B 和 C 已经出现的次数,如果当前字符是其中任何一个且计数过高,则返回 false。

int main() {
    int A_count = 0;
    int B_count = 0;
    int C_count = 0;

    std::cout << generate_string(20, [&] (int i, char c) {
            if (c == 'A') A_count++;
            if (c == 'B') B_count++;
            if (c == 'C') C_count++;
            if (A_count > 3 && c == 'A') return false;
            if (B_count > 4 && c == 'B') return false;
            if (C_count > 3 && c == 'C') return false;
            return true;
    });

    return 0;
}

还有健全性检查:

std::string test = generate_string(1000, [&] (int i, char c) {
        if (c == 'A') A_count++;
        if (c == 'B') B_count++;
        if (c == 'C') C_count++;
        if (A_count > 3 && c == 'A') return false;
        if (B_count > 4 && c == 'B') return false;
        if (C_count > 3 && c == 'C') return false;
        return true;
    });
std::cout << "A Count: " << std::count(test.begin(), test.end(), 'A') << std::endl;
std::cout << "B Count: " << std::count(test.begin(), test.end(), 'B') << std::endl;
std::cout << "C Count: " << std::count(test.begin(), test.end(), 'C') << std::endl;

输出:

A Count: 3
B Count: 4
C Count: 3

【讨论】:

  • std::uniform_int_distribution&lt;int&gt; dist(0, alphabet.size()); 分布构造函数中的区间在两端都是封闭的,这与大多数其他 STL 事物不同。数组索引可能会溢出。
  • @C.R.我现在正在尝试解决问题,我的答案将进行一些修改。
  • 另一个建议:使用&lt;random&gt; 生成种子的首选方式是std::random_device rd; auto seed=rd();
  • @C.R.谢谢,在生成随机数方面,我的经验有所不同,我选择了能够提供一致结果的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-26
  • 2013-08-29
  • 1970-01-01
  • 2014-03-17
  • 1970-01-01
  • 2011-04-01
  • 1970-01-01
相关资源
最近更新 更多