如何在使用动态 2D 数组时修复此代码

How to fix this code while using dynamic 2D array

本文关键字:代码 数组 2D 动态      更新时间:2023-10-16

我正在使用动态 2D 数组,需要特定索引的值,但它没有打印正确的值。

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

我希望输出是每个子集的值,但实际输出完全不同。

arr[i]=new int[n1];

人们对new所做的事情存在误解。(也许你来自爪哇?这不会存储值为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

这里

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比上面的选择更好。

如前所述,虽然您从动态分配的@Achal中得到了很好的答案,但您确实应该使用 C++ 提供的容器vector,以使事情变得更加轻松和健壮。所有C++容器都提供自动内存管理,使您不必手动分配(并且出错的可能性要小得多)

当使用容器(例如向量向量)来存储数据时,您可以简单地读取和丢弃您的"//elements in universal set""//no. of subset""//Elements in each subset"。使用容器时不需要这些值。您只需读取所需的值并将其添加到容器中,容器将根据需要增长以适应。

虽然不是 100% 清楚您的输入数据是什么样子的,但我们可以从您的文件中推断出它看起来像这样:

示例输入文件

其中第一个整数是读取数据不需要的"//elements in universal set"。同样,第二行,您的"//no. of subset"与读取数据无关。最后是每个数据行上的第一个元素,也不需要您的"//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 起),但如果编译不支持std=c++11,您可以自由使用传统for循环的.begin().end()容器函数)

示例使用/输出

将数据读入向量允许访问每个元素:

$ ./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

仔细查看,如果您有其他问题或我是否正确地解释了您的数据文件格式,请告诉我。

相关文章: