Получение одинаковой строки (генного массива) в каждом объекте массива dna (динамически распределяется) - PullRequest
4 голосов
/ 15 мая 2019

Я создал класс с именем DNA, имеющий конструктор без аргументов и две функции-члена, а именно initialize () и show (). Проблема в том, когда я создаю массив, используя оператор new и вызывая функцию initialize для каждого объекта, используя цикл for, вместо получения другой строки в переменной-члене "genes", я получаю точно такой же набор символов (массив) в genes в каждом объекте в массив. Хотя я инициализирую функцию srand () до инициализации строки, никакого эффекта от нее не видно.

Код ниже.

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
using namespace std;

string sampleSpace("ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz");

class DNA {
private:
    int length;
    char *genes;

public:
    DNA() {
        length = 0;
        genes = new char[length];
    }

    void initialize(int len) {
        srand(unsigned(time(NULL)));
        this -> length = len;
        delete genes;
        this -> genes = new char[length];

        for (int i = 0; i < length; i++) {
            *(genes + i) = sampleSpace.at(rand() % sampleSpace.length());
        }
    }

    void show() {
        for (int i = 0; i < length; i++) {
            cout<<*(genes + i);
        }
        cout<<endl;
    }
};

int main() {
    DNA *dna = new DNA[10];
    DNA *temp = dna;
    for (int i = 0; i < 10; i++) {
        (*temp).initialize(10);
        temp++;
    }
    temp = dna;
    for (int i = 0; i < 10; i++) {
        (*temp).show();
        temp++;
    }
    return 0;
}

Ответы [ 2 ]

1 голос
/ 15 мая 2019

Чтобы прокрутить ответ, данный здесь, эквивалентный ответ, но с использованием std::vector и std::generate:

#include <iostream>
#include <algorithm>
#include <ctime>
#include <string>
#include <vector>
#include <random>

std::string sampleSpace("ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz");

class DNA 
{
    private:
        std::vector<char> genes;

    public:
        void initialize(int len) 
        {
            static std::default_random_engine random;
            genes.resize(len);
            std::uniform_int_distribution<size_t> distribution{0, sampleSpace.length()-1};
            sampleSpace.at(distribution(random));
            std::generate(genes.begin(), genes.end(), [&] () 
                          { return sampleSpace.at(distribution(random)); });
        }

        void show() 
        {
           for (auto& v : genes)
                std::cout << v;
            std::cout << "\n";
        }
};

int main() 
{
    DNA dna[10];
    for (int i = 0; i < 10; i++) 
        dna[i].initialize(10);
    for (int i = 0; i < 10; i++) 
        dna[i].show();
}

Живой пример

Обратите внимание, что length также больше не нужен.

1 голос
/ 15 мая 2019

Вы должны использовать новый случайный API и использовать правильный механизм случайных чисел:

class DNA {
private:
    int length;
    std::unique_ptr<char[]> genes;

    static std::default_random_engine random;

public:
    DNA() : length{0}, genes{} {}

    void initialize(int len) {
        this-> length = len;
        this-> genes = std::make_unique<char[]>(length);

        std::uniform_int_distribution<std::size_t> distribution{0, sampleSpace.size() - 1};
        for (int i = 0; i < length; i++) {
            genes[i] = sampleSpace.at(distribution(random));
        }
    }

    void show() {
        for (int i = 0; i < length; i++) {
            cout<<genes[i];
        }
        cout<<endl;
    }
};

Это инициализирует std::default_random_engine и будет использовать правильное распределение номеров. Также я изменил код для уникального указателя.

Вот живой пример .

...