2016-07-19 100 views
3

我有一列数据(在4列),我想按特定列排序。它从文件读入2D矢量。我使用了std :: sort方法并编写了我的比较函子。该程序编译并运行,但是当我打印前10个元素时,它并未排序,但与添加到2D矢量的顺序肯定不同。排序的双向矢量

下面是代码:

#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 2 - 在Matrix data(4,Row(line_count));交换4line_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 

等等它去另有87万行左右。

+1

我感到困惑。不std :: sort照顾排序(因此交换)?为什么应该有一个交换功能? –

+1

使用矩阵数据(4,Row(line_count))''您正在声明一个类型为Row(line_count)'(line_count doubles的向量)的4个元素的向量。您应该在程序的其余部分将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不客气。很高兴有帮助。 –