2016-04-20 210 views
1

假设我们有一个matrix.txt文件矩阵,存储这样的:C++矩阵动态2D arrray

Image1

,我们希望把它改造成:

Image 2

数字8(第一个数字)表示二维数组有多大。之后,它的意思是: 1被连接到2(连接的值是1时,它总是1) 1连接到8 3被连接到4

而当转化到2D动态阵列,我们希望在ARRRAY 0,1 ... 0,7 ... 2,3中的值为1,所以(我没有使用方括号,因为stackoverflow将它们作为链接读取)。

int number; 
int **a = new int*[number]; 
for (int i = 0; i<number; i++) { 
    a[i] = new int[number]; 
} 
for (int i = 0; i<number; i++) { 
    delete[]a[i]; 
} 
    delete[]a; 

string line; 
ifstream myfile("matrix.txt"); 
if (myfile.is_open()) 
{ 
    getline(myfile, line); 
    istringstream(line)>> number; 


    while (getline(myfile, line)){ 
     cout << line << '\n'; 
     //HERE I SHOULD TURN THOSE NUMBERS INTO VALUES IN 2D ARRAY 
    } 
    myfile.close(); 
} 

所以我的问题是:我如何把这个数字变成矩阵二维数组?

谢谢

回答

2

最简单的办法,但可能不是最快的方法,是将线写入一个std::stringstream,然后回读出字符串流进行,列的,和价值变量。如果您从文件中读取数据,首先读取文件的成本通常会以缓慢的方式来分析文件的成本。如果它对你的情况很重要(并且首先确定它的代码,请查看手动解析文件)。也就是说,这个基本逻辑将成立。

while (getline(myfile, line)){ 
    cout << line << '\n'; 
    std::stringstream linestream(line); 
    int row; 
    int column; 
    int value; 
    if (linestream >> row >> column >> value) 
    { 
     a[row-1][column-1] = value; 
     a[column-1][row-1] = value;// mirror 
    } 
    else 
    { 
     // handle file formatting error 
    } 
} 

偏离主题,考虑使用矩阵类来管理你而不是原始2D数组。 The matrix class here at isocppp.org is good and fast,以及一些非常好的通用建议。

与isocpp矩阵上面的代码看起来像:

while (getline(myfile, line)){ 
    cout << line << '\n'; 
    std::stringstream linestream(line); 
    int row; 
    int column; 
    int value; 
    if (linestream >> row >> column >> value) 
    { 
     a(row-1,column-1) = value; 
     a(column-1,row-1) = value;// mirror 
    } 
    else 
    { 
     // handle file formatting error 
    } 
} 

几乎相同,更容易使用,因为你不必担心管理自己的记忆,周围路过的阵列尺寸很多,或一些错误的代码(例如a[4] = 0;)会占用阵列的一行。

附录

此代码

int number; 
int **a = new int*[number]; 
for (int i = 0; i<number; i++) { 
    a[i] = new int[number]; 
} 
for (int i = 0; i<number; i++) { 
    delete[]a[i]; 
} 
delete[]a; 

有两个严重的问题:

  1. a的大小与number,并number尚未分配。 number可能是从即时致命的负数(不能有负数大小的数组)到可能致命的巨大数字(您的计算机有9,223,372,036,854,775,807个字节的RAM字节)吗?不这么认为。)
  2. 分配后立即删除存储。释放内存是一个很好的习惯,但最好在使用之后释放内存,而不是之前。

所以:

// define `a` here 
string line; 
ifstream myfile("matrix.txt"); 
if (myfile.is_open()) 
{ 
    getline(myfile, line); 
    istringstream(line)>> number; 

    // allocate storage for `a` here 

    while (getline(myfile, line)){ 
     cout << line << '\n'; 
     //line reading code goes here 
    } 
    myfile.close(); 
} 
// delete `a` somewhere down here after it's been used. 
+0

当它尝试这种方式时,我得到一个错误,说a是未定义的。 –

+0

我所提供的全部是'//这里我应该把这些数字转化为二维数组中的值“以及围绕它的while循环。您仍然需要其余的代码来定义'a'并打开文件。 – user4581301

+0

除非你想要矩阵版本。在这种情况下,你需要'矩阵(数字,数字);'来想一想,你的数组定义中有一个令人讨厌的错误。编辑来帮助你解决这个问题。 – user4581301

1

建议你使用C++矢量从STL而不是2D数组c这是不安全的。

你可以这样做:

ifstream myfile("matrix.txt"); 

// Read matrix size 
size_t matrix_size = 0; myfile >> matrix_size; 

vector<vector<int> > matrix(matrix_size); 
for(size_t i=0; i < matrix.size(); ++i) matrix[i].resize(matrix_size); 
while(myfile.good()) 
{ 
    // Read row,col,val and set matrix value 
    int row=0, col=0, val=0; myfile >> row >> col >> val;  
    --row; --col; // Since your indices go from 1 to N 
    if(row < matrix_size && row >= 0 && col < matrix_size && col >= 0) { 
    matrix[row][col] = val; matrix[col][row] = val; 
    } 
} 
+0

比不安全的更多。该矢量更容易使用,在程序内部传递,并在清理后比动态分配的2D数组更清晰。也就是说,如果你想要获得良好的性能,可以使用一维向量,并用'row * number_columns + column'来伪造第二个维度。阅读“缓存未命中”对程序的影响。 – user4581301

+0

如果我理解了OP的文件格式,最终的矩阵似乎是对称的,只有右上部分存储在文件中... –

+0

Right @Bob__我错过了这一点。次优解决方案是在矩阵[col] [row]中添加相同的值。更好的解决方案是使用一个类来处理具有一维向量和正确的运算符[]的对称矩阵以进行访问。 – steiner