【问题标题】:How to do sorting in a text file in c++如何在 C++ 中对文本文件进行排序
【发布时间】:2020-12-26 17:07:46
【问题描述】:

我正在处理我的 C++(文件处理)项目,但遇到了问题

这是我的 .txt 文件

SNO, Name, NoOfPeopleLiked
1, The Shawshank Redemption, 77 
2, The Godfather, 20        
3, Into The Wild, 35
4, The Dark Knight, 55      
5, 12 Angry Men, 44
6, Schindler's List, 33
7, The Lord of the Rings: The Return of the King, 25
8, Pulp Fiction, 23
9, The Good, the Bad and the Ugly, 32   
10, The Lord of the Rings: The Fellowship of the Ring, 56

我必须显示关于NoOfPeopleLiked前 5 部电影 就像这样:

样本输出

1, The Shawshank Redemption, 77
2, The Lord of the Rings: The Fellowship of the Ring, 56
3, The Dark Knight, 55
4, 12 Angry Men, 44
5, Into The Wild, 36

所以我必须进行排序,这就是我到目前为止所做的


void topFive()
{
    Movies v[20];       //class object array
    fstream top;        //for reading
    top.open("movies.txt");

    for (int h = 0; h < 10; h++) // reading from txt file
    {
        top >> v[h].serial >> v[h].movieName >> v[h].liked; 
    }
    // run loops two times: one for walking throught the array
    // and the other for comparison
    for (int step = 0; step < 5; ++step) 
    {
        for (int i = 0; i < 5 ; ++i) 
        {

            // To sort in descending order, change > to < in this line.
            if (v[i].liked > v[i + 1].liked) 
            {

                // swap if greater is at the rear position
                int temp = v[i].liked;
                v[i].liked = v[i + 1].liked;
                v[i + 1].liked = temp;
            }
        }
    }
    //  to print the array
    for (int i = 0; i < 5; ++i)
    {
        cout << v[i].serial << ", " << v[i].movieName << ", " << v[i].liked << endl;
    }
}   

老实说,我不知道如何完美地做到这一点,我被这个问题困扰了大约 6-7 个小时,仍然无法做出任何逻辑。我希望你们能帮助我并更好地指导我。在此先感谢:)

【问题讨论】:

  • 你想在这里使用std::sort。您需要为其提供一个比较函数,该函数与您当前的比较函数没有太大区别。或者,如果您想继续自己滚动,则需要告诉我们您观察到的问题所在。
  • 首先您要读取以逗号分隔的字段,top &gt;&gt; v[h].serial &gt;&gt; v[h].movieName &gt;&gt; v[h].liked; 不是这样做的方法
  • 电影 #9 有解析复杂性,因为标题中有一个逗号。
  • 您可以逐行解析文件并将正则表达式应用于每一行...
  • 感谢您的代码无法正常工作。但是你需要描述它是如何不工作的。你的向量中有合理的对象吗?您的排序没有按正确的顺序排序吗?

标签: c++ file-handling


【解决方案1】:

我已经使用std::regex 模块实现了下一个解决方案。加上一些字符串操作。还有原因排序!

在我的代码输入文件名为0302.txt,请在运行代码之前将其重命名为您需要的名称。

Try it online!

#include <vector>
#include <string>
#include <regex>
#include <fstream>
#include <tuple>
#include <iostream>
#include <stdexcept>
#include <algorithm>

int main() {
    try {
        auto StrTrim = [](std::string & str){
            str.erase(0, str.find_first_not_of("\t\n\v\f\r ")); // left trim
            str.erase(str.find_last_not_of("\t\n\v\f\r ") + 1); // right trim
        };
        std::ifstream ifile("0302.txt");
        std::string line;
        std::vector<std::string> lines;
        // Read all lines of file.
        while (std::getline(ifile, line)) {
            StrTrim(line);
            if (line.empty())
                continue;
            lines.push_back(line);
        }
        if (!lines.empty())
            lines.erase(lines.begin(), lines.begin() + 1); // remove first header line
        lines.erase(lines.begin(), lines.begin() + 1); // remove first header line
        std::vector<std::tuple<size_t, std::string, size_t>> data;
        std::regex re(R"((\d+)\s*,\s*(.+)?\s*,\s*(\d+))");
        for (auto const & line: lines) {
            std::smatch matches;
            if (std::regex_match(line, matches, re)) {
                if (matches.size() != 4)
                    throw std::runtime_error("Matched line with not 3 elements: '" + line + "'!");
                data.push_back(std::make_tuple(size_t(std::stoi(matches[1])), matches[2], size_t(std::stoi(matches[3]))));
            } else
                throw std::runtime_error("Unmatched line: '" + line + "'!");
        }
        std::sort(data.begin(), data.end(), [](auto const & l, auto const & r){
            return std::get<2>(l) > std::get<2>(r);
        });
        for (size_t i = 0; i < 5; ++i) {
            if (i >= data.size())
                break;
            std::cout << (i + 1) << "|" << std::get<0>(data[i]) << ", " << std::get<1>(data[i]) << ", " << std::get<2>(data[i]) << std::endl;
        }
        return 0;
    } catch (std::exception const & ex) {
        std::cout << "Exception: " << ex.what() << std::endl;
        return -1;
    }
}

输入文件0302.txt:

SNO, Name, NoOfPeopleLiked
1, The Shawshank Redemption, 77 
2, The Godfather, 20        
3, Into The Wild, 35
4, The Dark Knight, 55      
5, 12 Angry Men, 44
6, Schindler's List, 33
7, The Lord of the Rings: The Return of the King, 25
8, Pulp Fiction, 23
9, The Good, the Bad and the Ugly, 32   
10, The Lord of the Rings: The Fellowship of the Ring, 56

控制台输出:

1|1, The Shawshank Redemption, 77
2|10, The Lord of the Rings: The Fellowship of the Ring, 56
3|4, The Dark Knight, 55
4|5, 12 Angry Men, 44
5|3, Into The Wild, 35

【讨论】:

    【解决方案2】:

    您可以将文件中的字符串插入向量中,然后使用自定义比较器函数进行排序。这个比较器函数可以从输入字符串中提取排名(假设排名在最后一个逗号之后,假设输入模式是统一的)并将其用于比较。代码:

    #include <iostream>
    #include <string>
    #include <vector>
    #include <algorithm>
    #include <sstream>
    #include <fstream>
    
    using namespace std;
    
    int get_rank(std::string input) {
        std::stringstream ss(input);
        std::string s;
        // keep extracting strings, last one would be your 'int' rank
        for(; ss >> s; );
        return std::atoi(s.c_str());
    }
    
    int main() {
        std::ifstream infile("movies.txt");
        std::vector<std::string> v;
        std::string line;
        std::getline(infile, line);
        for( ; getline( infile, line ); )
            v.push_back(line);
        std::sort(v.begin(), v.end(), [](std::string s1, std::string s2) -> bool { return get_rank(s1) > get_rank(s2); });
        for(int i = 0;i < 5;i++)
            cout << i + 1 << "," << v[i].substr(v[i].find(",") + 1) << endl;
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2021-11-23
      • 2019-02-04
      • 1970-01-01
      • 2019-09-30
      • 1970-01-01
      • 1970-01-01
      • 2011-04-04
      • 2011-10-15
      相关资源
      最近更新 更多