2013-11-29 3 views
-2

Я хочу создать случайную строку длины m * j, где m = 4, j = 3, например. Я сделал этоСоздать случайную строчку с ограничениями в C++

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

Я держал StringLength = 3, так что возвращаемое значение состоит только из первых трех алфавитов (A, B, C), в случайном порядке длины 20

что я хочу теперь нужно иметь случайную строку, которая имеет A всего 3 раза B всего 4 раза и C всего 3 раза. Как применить эти ограничения? Счетчики?

Hi, Я сделал что-то подобное, как предлагалось в ответе. Вот код

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; 
} 

Но выход имеет некоторые символы хвостовых не могут понять, что они Вот скриншот screenshot

+0

Почему дд добавить теги C и объектно-ориентированного программирования? – ThiefMaster

+0

Причина, по которой у вас есть барахло в конце строки, вы не завершаете NULL. –

+0

Спасибо @RetiredNinja Теперь я получаю правильный результат :-) – 8A52

ответ

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; 
    } 

Наш предикат здесь передается как лямбда. Для простоты я подсчитываю, сколько раз 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 
+1

'std :: uniform_int_distribution dist (0, alphabet.size());' Интервал в конструкторе распределения закрыт с обоих концов, в отличие от большинства других STL вещи. Индексирование массива может переполняться. –

+1

@ C.R. Я пытаюсь исправить кинки прямо сейчас, на мой ответ будет несколько изменений. –

+1

Другой совет: с '' предпочтительным способом генерации семени является 'std :: random_device rd; auto seed = rd(); '. –

Смежные вопросы