2016-07-19 14 views
3

私はある列でソートしたいデータのリストを(4列で)持っています。それはファイルから2Dベクトルに読み込まれました。私はstd :: sortメソッドを使用し、コンパレータファンクタを書きました。プログラムはコンパイルされ実行されますが、最初の10個の要素を印刷するとソートされませんが、2Dベクトルに追加された順序とは確かに異なります。ここで2倍の2次元ベクトルをソート

はコードです:

#include <iostream> 
#include <fstream> 
#include <stdio.h> 
#include <string> 
#include <vector> 
#include <algorithm> 
#include <iomanip> 

using namespace std; 

typedef vector<double> Row; 
typedef vector<Row> Matrix; 

bool sortByFourthColumn(const Row& row1, const Row& row2){ 
    return (double) row1[3] < (double) row2[3]; 
} 

int main(){ 
    std::ifstream infile; 
    infile.open("Test8_Output.txt"); 

    double x,y,z,E; 
    char line[200]; 
    int line_count=0; 

    ofstream outfile; 
    outfile.open("WO_crp.txt"); 

    if (infile.is_open()){ 

     while (!infile.eof()){ 
      infile.getline(line,170); 

      if (line[0] != '%'){ 
      outfile<<line<<"\n";   
      line_count++; 
      } 
      else{ 
      } 
    } 

    Matrix data(line_count,Row(4)); 

    outfile.close(); 

    std::ifstream myfile; 
    myfile.open("WO_crp.txt"); 

    int i = 0; 
    while(myfile >> x >> y >> z >> E){ 
     data[0][i] = x; 
     data[1][i] = y; 
     data[2][i] = z; 
     data[3][i] = E; 
     i++; 
    } 
    myfile.close(); 

    std::sort(data.begin(), data.end(), sortByFourthColumn); 

    for (int u = 0; u <20; u++){ 
     cout << setprecision(5) << data[0][u] << "\t" << setprecision(5)<< data[1][u] << "\t" << setprecision(5)<< data[2][u] << "\t" << setprecision(5)<< data[3][u] << endl; 
    } 

    } 
    else{ 
     cout << "Error: File is invalid.\n"; 

    } 
    return(0); 
} 

EDIT - 入力ファイルがどのように見えるかのサンプル:
EDIT 2 - その上Matrix data(4,Row(line_count));

% Model:    CDS_Test8.mph 
% Version:   COMSOL 5.2.0.220 
% Date:    Jul 13 2016, 14:33 
% Dimension:   3 
% Nodes:    86183 
% Expressions:  1 
% Description:  Electric field norm 
% Length unit:  m 
% x      y      z      es.normE (V/m) 
0.13774675805195374  0.05012986567931247  0.20735     67.35120820901535 
0.13870000000000005  0.04957489750396299  0.20735000000000003  102.8772500513651 
0.13870000000000002  0.050800000000000005  0.20735     87.56008679032011 
0.13792733849817027  0.050131465727838186  0.20801419247484804  73.55192534768238 
0.13674627634411463  0.04992349737428063  0.20735     63.23018910026428 
0.13750191177019236  0.0508     0.20735000000000003  67.26176884022838 
0.13827743496772454  0.05193409099097887  0.20734999999999998  73.35474409597487 
0.13803618792088135  0.05134931748395268  0.20841988134890965  75.3712126982815 
0.13905949760011943  0.05141879754884912  0.20734999999999998  83.70739713476813 
0.13896970815034013  0.05092428105421264  0.208142746399683  84.73571510992372 
0.1390220807917094  0.0501245422629353  0.20817502757007986  85.57119242707628 
0.13944867847480893  0.05161480113017738  0.2081969878426443  89.65643851109644 

そしてそうで4line_countを入れ替え行きます別の87kライン程度。

+1

私は混乱しています。 std :: sortはソートを扱いません(したがってスワッピングも行いますか?)なぜスワップ機能が必要ですか? –

+1

'Matrix data(4、Row(line_count)) 'では、' Row(line_count) '型の4要素のベクトル(line_count doubleのベクトル)を宣言しています。プログラムの残りの部分では、line_countと4を入れ替える必要があります。 –

+0

この@Bob__を見つけていただきありがとうございます。理由を理解できませんでしたが、変更を実装しました。出力は「もっと」現在ソートされているように見えます。しかし、そうではありません。それは正確な問題だろうか? –

答えて

2

私は の特定の列で並べ替えるデータのリスト(4列)を持っています。

問題は、OPプログラムにデータを格納するために使用されるベクトルのベクトルの次元が、宣言と使用の間で一貫していないことです。

while(!infile.eof()){...should be avoidedを使用するのがマイナーな問題です。

修正版は次のようである:

#include <iostream> 
#include <fstream> 
#include <sstream> 
#include <string> 
#include <vector> 
#include <array> 
#include <algorithm> 
#include <iomanip> 

using Row = std::array<double,4>;  // instead of typedefs 
using Matrix = std::vector<Row>; 
using std::cout; 

bool sortByFourthColumn(const Row& row1, const Row& row2){ 
    return row1[3] < row2[3]; 
    // ^The cast is unnecessary 
} 

int main(){ 

    std::string file_name{"Test8_Output.txt"}; 
    std::ifstream infile{file_name, std::ios_base::in}; 
    if (!infile) { 
     cout << "Error: unable to open file " << file_name << '\n'; 
     return EXIT_FAILURE; 
    } 

    Matrix data; 
    data.reserve(90000); // if you are afraid of the reallocations 
    int count = 0; 
    std::string line; 

    // instead of two loops you can use one loop and read the file once 
    // I'll use std::getline to extract a row in a std::string 
    while (std::getline(infile, line)) { 
     // skip comments and empty lines 
     if (line.empty() || line[0] == '%') 
      continue; 
     ++count; 

     // extract data from the string using a stringstream 
     std::stringstream ss{line}; 
     Row r; 
     ss >> r[0] >> r[1] >> r[2] >> r[3]; 
     if (!ss) { 
      cout << "Format error in line " << count << " of file.\n"; 
      break; 
     } 
     data.push_back(std::move(r)); 
    } 

    std::sort(data.begin(), data.end(), sortByFourthColumn); 
    cout << std::setprecision(5) << std::fixed; 

    for (const auto & r : data) { 
     for (auto const &x : r) { 
      cout << std::setw(10) << x; 
     } 
     cout << '\n'; 
    } 
    return EXIT_SUCCESS; 
} 

出力は、例えばデータ与えられる:

0.13675 0.04992 0.20735 63.23019 
    0.13750 0.05080 0.20735 67.26177 
    0.13775 0.05013 0.20735 67.35121 
    0.13828 0.05193 0.20735 73.35474 
    0.13793 0.05013 0.20801 73.55193 
    0.13804 0.05135 0.20842 75.37121 
    0.13906 0.05142 0.20735 83.70740 
    0.13897 0.05092 0.20814 84.73572 
    0.13902 0.05012 0.20818 85.57119 
    0.13870 0.05080 0.20735 87.56009 
    0.13945 0.05161 0.20820 89.65644 
    0.13870 0.04957 0.20735 102.87725 
+0

重要な間違いを指摘していただきありがとうございます。私はプログラムが働いている。私はあなたのバージョンのほとんどを実装します - それははるかに合理化されています。 –

+0

@ChamiSangeethAmarasinghe大歓迎です。役に立つと嬉しいです。 –