2016-07-19 4 views
3

У меня есть список данных (в 4 столбцах), которые я хотел бы отсортировать по определенному столбцу. Он был прочитан из файла в 2D-вектор. Я использовал метод std :: sort и написал свой функтор компаратора. Программа компилируется и запускается, но когда я печатаю первые 10 элементов, она не сортируется, но, конечно, отличается от того, что она была добавлена ​​в 2D-вектор.Сортировка 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 - образец того, что входной файл выглядит следующим образом:
EDIT 2 - поменять местами 4 и line_count в 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 

И так далее она идет для других 87k строк или около того.

+1

Я запутался. Не std :: sort заботится о сортировке (и, следовательно, обменивается)? Почему должна быть функция свопинга? –

+1

С 'Matrix data (4, Row (line_count))' вы объявляете вектор из 4 элементов типа 'Row (line_count)' (вектор double_count). Вы должны поменять местами 4 с помощью line_count и т. Д. В остальной части программы. –

+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 Добро пожаловать. Рад быть полезным. –

Смежные вопросы