2016-10-02 162 views
0

我具有存儲在格式未知形狀的像如何將逗號分隔數字矩陣放入C++中的動態分配數組中?

-1,4,12,5.7 
2.1,3,-10,3.3 
7.1,1.11,12,10 

若干矩陣I嘗試將矩陣存儲在動態分配的陣列的文件,因爲我不能硬編碼的行和列的數量。對於這一部分,我用指針到指針和一個演示是如下,

#include <iostream> 
using namespace std; 

int main() 
{ 
    // Rather than user input, I need to change this part to deciding the shape of the matrix myself 
    int row, col; 
    cout << "Enter row number and column number, separated with a space:\n"; 
    cin >> row >> col; 
    int** p_p_grid = new int* [row]; 
    for(int i = 0; i < row; i++) 
    { 
     p_p_grid[i] = new int[col]; 
    } 

    // Fill in the entries 
    for(int i = 0; i < row; i++) 
    { 
     for(int j = 0; j < col; j++) 
     { 
      // (i + 1) * (j + 1) needs to be replaced by true entries in the matrix 
      p_p_grid[i][j] = (i + 1) * (j + 1); 
     } 
    } 
    return 0; 
} 

但是,什麼是指定一個個號碼之前決定以逗號分隔的數塊的形狀的有效途徑?而且我該如何在C++中導入CSV結構的矩陣? (出於某種原因,我不希望使用矢量型,所以請關注陣列上)

+2

如果你使用'new []'作爲動態數組,那麼你做錯了。正確的方法是使用['std :: vector'](http://en.cppreference.com/w/cpp/container/vector)。那麼你不必擔心行和列的數量,它將是完全動態的。你甚至可以有不同數量的列的行。這是真的,如果你需要動態數組,你可以使用'std :: vector'。你「想要」或沒有真正重要的IMO,正確的答案是矢量。 –

+0

謝謝,但是如果'vector'沒有被使用,有沒有辦法呢?@JoachimPileborg – Nicholas

+0

順便說一句,當你說'new [] for dynamic arrays you do it wrong it',你是說有更好的方法而不是'new []'或者你是否在我的代碼中提示有任何錯誤?@JoachimPileborg – Nicholas

回答

1

什麼是決定一個逗號形狀的有效方式分配之前分離 數塊一個接一個?

假設您正在從文件流中讀取數據,最簡單的方法是讀取文件兩次:一個用於計算行和逗號,一個用於進行實際輸入。

這裏如何檢測矩陣,回採結束時,一個新的行元素的數量不匹配矩陣格式的例子:

int nrows=1, ncols=0; 
string line; 
while (getline(ifs, line)) { 
    int n=1; 
    for (auto x: line) // count commas in the line 
     if (x==',') 
      n++; 
    if (!ncols) 
     ncols = n;  // first line sets th enumber of columns 
    else if (n == ncols) // subsequent lines increase the row count 
     nrows++; 
    else break;   // unless the format does'n match anymore 
} 
ifs.clear(); // remove eof 
ifs.seekg (0, ifs.beg); // rewind 

Online demo

什麼導致這種方法缺乏效率,是你讀了兩次文件。出於這個原因,順便說一句,你不能使用這種方法來閱讀cin:你不能倒帶。

您可以通過緩存行讀取(但您需要管理一個字符串劃分數組,因爲您不允許使用矢量)或通過讓矩陣動態增長(不再對應於你的問題,因爲這不會提供矩陣大小)。

我如何導入C++

在每行一個CSV結構矩陣,剛讀雙打,其次是一個char(這應該是 ''):

char forget_me; 
for (int i=0; i<nrows; i++) 
    for (int j=0; j<ncols; j++) { 
     cin >> p_p_grid[i][j]; 
     if (j<ncols-1) 
      cin>>forget_me; 
    } 
1

我知道你不想一個vector基於解決方案,但這裏有一個無論如何

int main() { 
    ifstream input("input.txt"); 
    if(!input) { 
     cerr << "couldn't open file" << endl; 
     exit(1); 
    } 

    double number; 
    vector<vector<double>> matrix; 
    vector<double> current_row; 
    while(input >> number) { // loop once for each number in the file 
     current_row.push_back(number); 
     int next_char = input.get(); // should be ',' or '\n' 
     if(next_char == '\n') { 
      // current row is finished 
      matrix.push_back(current_row); 
      current_row.clear(); 
     } 
    } 

    // now print the matrix back out again 
    for(auto const & one_row : matrix) { 
     for(auto one_number : one_row) { 
      cout << "\t," << one_number; 
     } 
     cout << endl; 
    } 
} 
1

它有點狡猾。使用C++ iostream或C stdio.h,然後讀入整行。所以如果使用getline/fgets,你需要一個非常大的緩衝區,比如說8k。現在,第一行解析字段。對於第一次嘗試,只需計算逗號,但實際的規則比這更復雜。

一行接一行地提取數據。由於您沒有對行數進行說明,除了動態增長每行的緩衝區外,別無選擇。 STL向量可以讓你輕鬆實現 - 只需將其推回,緩衝區就會增長。但是,如果你願意,你可以用這個結構

int **p_p_grid = 0; 
int Nrows = 0; 
int Ncolumns = 0; 

/* (for first line, fill the number of columns) */ 
/* for each line */ 
p_p_grid = realloc((Nrows + 1) * sizeof(int *)); 
if(!p_p_grid) 
    memory_failure(); 
p_p_grid[Nrows] = malloc(Ncolums * sizeof(int)); 
if(!p_p_grid[Nrows]) 
    memory_failure(); 
for(i=0;i<Ncolumns;i++) 
    p_p_grid[Nrows][i] = /* parse logic here */ 
Nrows++; 
0

正如指出的那樣,我會用std::vector代替。考慮到每行都有固定數量的元素,我也會使用std::array。也許做這樣的事情:

#include <vector> // For std::vector 
#include <array> // For std::array 
#include <string> // For std::string and std::getline 
#include <fstream> // For std::ifstream 
#include <sstream> // For std::isstream 

int main() 
{ 
    std::vector<std::array<double, 4>> grid; 

    std::ifstream input{"input.txt"}; 

    std::string line; 

    // Outer loop reads the rows 
    while(std::getline(input, line)) 
    { 

     int i = 0; 
     std::istringstream iss{line}; 

     std::array<double, 4> values; 
     double value; 

     // Inner loop extracts the values on each row 
     while (iss >> value) 
     { 
      values[i] = value; 

      // Skip over the comma 
      iss.ignore(std::numeric_limits<std::streamsize>::max(), ','); 
     } 

     grid.push_back(values); 
    } 

    // Now print the values 
    int row_number = 1; 
    for (auto const& row : grid) 
    { 
     std::cout << "Row " << row_number++ << ": "; 

     for (auto const value : row) 
     { 
      std::cout << value << ' '; 
     } 

     std::cout << '\n'; 
    } 
} 

請注意,我並沒有實際測試上面的代碼。它雖然編譯乾淨。

相關問題