Я пытаюсь создать случайную двоичную строку, которая состоит из 0 и 1. В моей реализации я генерирую случайные целые числа 0 и 1, а затем использую std :: to_string (), чтобы привести их к типу и вставить в другую строку. Проблема, которая у меня есть, заключается в том, что с помощью std :: to_string () для вставки символов «0» или «1» я также вставляю завершающий нулевой символ «\ n», и поэтому я удваиваю размер строка. Например, скажем, я хочу создать строку, состоящую из Nbits = 10 символов. В приведенной ниже реализации я получаю строку из 10 элементов, напечатанную на экране, однако размер строки вдвое больше. Ты знаешь, как я мог избежать этого?
Проблема с размером заключается в том, что я пытаюсь написать двоичное представление генетического алгоритма, и мне нужно, чтобы размер был правильным, чтобы операторы кроссовера / мутации были правильными.
#include <iostream>
#include <string>
#include <random>
using namespace std;
std::random_device rd;
std::mt19937 gen(rd());
// Random bit string generator
string random_string(size_t Nbits){
std::uniform_int_distribution<> int1(0,1);
string s;
s.resize(Nbits);
for(size_t i=0; i<Nbits; i++)
s.insert(i,to_string(int1(gen)));
return s;
};
int main(){
// Say I want a 10 bits random binary string
size_t Nbits=10;
string s=random_string(Nbits);
// If I print my string on screen, it has the correct number of entries:
cout<<s<<endl;
// However the size of the string is not equal to the number of entries.
cout<< "Number of bits is: "<< Nbits<<", length of string is "<< s.size()<<endl;
}
Возможный вывод:
1001111111
Number of bits is: 10, length of string is 20
Ваша логика вставки преобразует значения, которые ей не нужны. Нет смысла преобразовывать данные в строку битов, где вы уже знаете возможные результаты каждого бита: 0
или же 1
,
А также .insert()
это неправильный метод. Вы складываете данные в строку, которая уже была предварительно измерена, тем самым добавляя Больше символы, не заменяя их. Вы должны начать с пустой строки, затем вставить данные, резервируя при желании (но не обязательно).
Попробуй это:
std::string random_string(size_t Nbits)
{
std::uniform_int_distribution<> int1(0,1);
string s;
s.reserve(Nbits);
for (size_t i=0; i<Nbits; i++)
s.push_back(int1(gen) ? '1' : '0');
return s;
};
В качестве альтернативы, используйте тот факт, что '0'
а также '1'
гарантированно будут смежными значениями по стандарту, и, возможно, вместо этого сделайте что-то вроде этого:
std::string random_str(size_t Nbits)
{
std::string s;
std::generate_n(std::back_inserter(s), Nbits,
std::bind(std::uniform_int_distribution<char>('0', '1'),std::ref(gen)));
return s;
}
Есть множество способов сделать это, только некоторые из них упомянуты здесь. Удачи.
В функции random_string
вы создаете строку Nbits
символы, что означает, что его размер Nbits
, Затем вы вставить символы, делая строку длиннее.
Есть два очевидных решения: одно из них заключается в использовании i
в качестве индекса в строку, и установите этот символ. Другой — вообще не устанавливать размер, а просто добавлять новые символы.
Другим решением для создания случайной двоичной строки было бы сначала создать случайное значение:
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, 20);
int val = dis(gen);
Затем передайте это случайное значение в качестве входного аргумента следующему числу в двоичный преобразователь строк:
template<typename T>
std::string to_binary_string(T const &val) {
return std::string(std::bitset<sizeof(T) * CHAR_BIT>(val).template to_string<char,std::string::traits_type,std::string::allocator_type>());
}