Как исправить этот код при использовании динамического 2D-массива - PullRequest
0 голосов
/ 24 марта 2019

Я использую динамический двумерный массив и мне нужно значение определенного индекса, но оно не печатает правильное значение.

```int u=5;//No. of elements
int S[u];
int i=0;
while(i<u)//elements in universal set
{
    cin>>S[i];
    i++;
}
int n;
cin>>n;//no. of subset
i=0;
int subcost[n];
int **subset;
subset=new int*[n];
while(i<n)
{
    int l,c;
    cin>>l;//size of ith subset
    subset[i]=new int[l];
    int j=0;
    while(j<l)//Elements in each subset
    {
        cin>>subset[i][j];
        j++;
    }
    cin>>c;//cost for each subset
    subcost[i]=c;
    i++;
}

i=0;
while(i<n)
{
    int j=0;
    int s=*subset[i];
    while(j<s)
    {
        cout<<subset[i][j]<<"\n";
        j++;
    }
    i++;
}```

Я ожидаю, что выходной будет значением каждого подмножества, но фактическим выходнымсовершенно другой.

Ответы [ 3 ]

0 голосов
/ 24 марта 2019

Здесь

arr[i]=new int[n1]; /* allocating memory for arr[i], equal to n1*sizeof(int) bytes & arr[i] gets points to address returned by new */
cout<<"Value of "<<i<<"th row is :- "<<arr[i]<<"\n";

Я ожидаю, что на выходе будет значение n1, но фактический результат равен некоторым случайный адрес ?

да, arr[i] - это динамически создаваемый массив, и при печати он печатает только свой базовый адрес.

Попробуйте эту версию, где я пытался объяснить изменения кода в комментариях.

int main(void) {
    std::cout<<"Enter the value of n"<<"\n";
    int n;
    std::cin>>n;
    int **arr;
    /* allocate memory for arr. arr holds base address of array of n int ptr */
    arr=new int*[n];
    int i=0;
    int n1;
    std::cout<<"Enter the value of n1"<<"\n";
    std::cin>>n1;
    /* allocate memory for arr[0], arr[1] .. */
    while(i < n1) {
        arr[i]=new int[n1];
        i++;
    }
    /* put the data into dynamically allocated array */
    for(int row = 0; row < n; row++) {
        for(int col = 0; col < n1; col++) {
            std::cin>>arr[row][col];
        }
    }
    /* printh te data */
    for(int row = 0; row < n; row++) {
        for(int col = 0; col < n1; col++) {
            std::cout<<"Value of "<<i<<"th row is :- "<<arr[row][col];
        }
        std::cout<<"\n";
    }
    return 0;
}

И поскольку вы создали динамический массив с использованием new, вам необходимо освободить динамически выделенную память, чтобы избежать утечки памяти, соответственно используйте оператор delete.

Как указано другими, std::vector - лучший вариант, чем выше.

0 голосов
/ 24 марта 2019

Хотя у вас есть хороший ответ от @Achal для динамического размещения, как уже упоминалось, вам действительно следует использовать контейнер vector, предоставляемый C ++, чтобы сделать вещи намного проще и надежнее.Все контейнеры C ++ обеспечивали автоматическое управление памятью, освобождая вас от необходимости выделять вручную (и с гораздо меньшей вероятностью ошибиться)

При использовании контейнеров, таких как вектор векторов, для хранения ваших данных, вы можете просто прочитатьи откажитесь от своих "//elements in universal set", "//no. of subset" и "//Elements in each subset".Эти значения не требуются при использовании контейнеров.Вы просто читаете значение, которое хотите, и добавляете его в свой контейнер, контейнер будет увеличиваться по мере необходимости.

Хотя неясно на 100%, как выглядят ваши входные данные, мы можем вывести их из вашего файла.выглядит примерно так:

Пример входного файла

Где ваши первые целые числа - это "//elements in universal set", который не нужен для чтения данных.Как и во второй строке, ваш "//no. of subset" не имеет значения для чтения данных.Наконец, 1-й элемент в каждой строке данных, ваш "//Elements in each subset" также не нужен.Каждое из этих значений просто читается и отбрасывается для получения окончательного набора данных.

$ cat dat/universal_sub.txt
5
4
5 1 2 3 4 5
3 1 2 3
4 1 2 3 4
6 1 2 3 4 5 6

Окончательный набор данных, который вы хотите сохранить

Из полного файла,Похоже, что это фактические значения данных, которые вы хотите сохранить (может быть четное число, но для этого нет необходимости)

1 2 3 4 5
1 2 3
1 2 3 4
1 2 3 4 5 6

Существует множество различных способов объединения частей.Краткий пример того, как получить окончательный набор данных из входного файла:

#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <limits>

int main (void) {

    std::string line;                       /* string for reading each line */
    std::vector<std::vector <int>> subset;  /* vector<vector<int>> */
    int universal, nsubsets;                /* two int to read/discard */

    if (!(std::cin >> universal >> nsubsets)) { /* read/dicard 2 values */
        std::cerr << "error: failed to read universal.\n";
        return 1;
    }
    /* read/discard '\n' (any chars) left in input buffer line by cin above */
    std::cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');

    while (getline (std::cin, line)) {  /* read each remaining data line */
        int unneeded, i;                /* 1st value and i for rest */
        std::vector<int> tmp;           /* vector<int> for each line */
        std::stringstream ss (line);    /* stringstream to read from */
        if (ss >> unneeded) {           /* read/discard 1st value */
            while (ss >> i)             /* read rest from stringstream */
                tmp.push_back(i);       /* add to tmp vector */
            subset.push_back(tmp);      /* add tmp vector to subset */
        }
    }

    for (auto& i : subset) {        /* loop over subsets */
        for (auto& j : i)           /* loop over each value in subset */
            std::cout << " " << j;  /* output value */
        std::cout << '\n';          /* tidy up with newline */
    }
}

( примечание: в выходных циклах используется цикл for на основе диапазона .(начиная с C ++ 11) , но вы можете использовать контейнерные функции .begin() и .end() с традиционным циклом for, если ваша компиляция не поддерживает std=c++11)

Пример использования / вывода

Считывание ваших данных в вектор векторов позволяет получить доступ к каждому элементу:

$ ./bin/vector_2d_subset < dat/universal_sub.txt
 1 2 3 4 5
 1 2 3
 1 2 3 4
 1 2 3 4 5 6

Посмотрите вещи и дайте мне знать, если у вас есть дополнительные вопросы илиесли я неверно истолковал ваш формат файла данных.

0 голосов
/ 24 марта 2019
arr[i]=new int[n1];

Есть неправильное понимание того, что делает new. (Возможно, вы пришли из Java?) Это не хранит целое число со значением n1. Вместо этого он создает массив размером n1.

Для массива достаточно одного уровня указателя:

int n = 5;
int i = 0;

int *arr;
arr = new int[n];
arr[i] = 100;

cout << arr[i] << endl;  // output: 100


delete[] arr;  // remember to deallocate – otherwise memory leaks will haunt your system!

Если вы ищете 2D-массив, будет работать указатель на указатель (**).

int **arr;
arr = new int[n];       //
arr[0] = new int[n];    //  allocate first array
arr[0][0] = 100;        //  set first element of first array

delete[] arr[0];
delete[] arr;           //  deallocate
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...