具有catch的文件的线性词典排序

时间:2017-10-02 11:46:56

标签: c++ sorting

虽然我对这个问题的标题不满意,但这可能是一个奇怪的问题;拜托我,请。

所以我的文本文件内容如下:

 & AAABBAB
 this
 & AAAAAAB 
 is
 & BCAAAA
 an
 & BBBBBA
 example
 & BABABAB
 text

其他所有行都以标识符开头('&')。具有所述标识符的行应按字典顺序排序,但我需要它以使下一行随之拖动到输出文件中的新位置。

这就是我希望成为输出文件的内容。

 & AAAAAAB 
 is
 & AAABBAB
 this
 & BABABAB
 text
 & BBBBBA
 example
 & BCAAAA
 an

有了这个,我可以逐行获取文件内容:

#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>

using namespace std;

int main()
{
    ifstream is("test.txt");
    string str;
    while(getline(is, str))
    {
        cout<<str<<endl;
    }
    return 0;
}

有没有一种简单的方法来完成我想要的东西?谢谢你的帮助!

4 个答案:

答案 0 :(得分:3)

我会在阅读时将这些对捆绑在一起,使它们易于排序:

vector<pair<string, string>> vec; // first is identifier
vec.reserve(1000);

bool first = true;
while(getline(is, str))
{
    if (first)
        vec.emplace_back(str, string());
    else
        vec.back().second = str;
    first = !first;
}

sort(vec.begin(), vec.end());

答案 1 :(得分:2)

您可以成对地将您的线条收集到std::pair<std::string, std::string>

的向量中
using line_t = std::pair<std::string, std::string>;
std::vector<line_t> lines;
line_t pair_line;
while (std::getline(is, pair_line.first) &&
       std::getline(is, pair_line.second)) {
    lines.push_back(pair_line);
}

按照.first

对它们进行排序
std::sort(begin(lines), end(lines),
          [](auto const &l1, auto const &l2)
            { return l1.first < l2.first; });

DEMO

答案 2 :(得分:1)

是的,有。

将整个文件视为键和值对的映射,读入std::map<std::string,std::string>,然后输出映射。由于字符串比较默认为字典,而地图具有有序键,因此地图将为您进行排序。

答案 3 :(得分:1)

如果你的文件太大而无法存储在内存中,或者通常你需要效率,那么这是一个非常有效的方法。

它结合了

  • 内存映射¹
  • stringviews²
  • 标准算法

<强> Live On Coliru

#include <boost/iostreams/device/mapped_file.hpp>
#include <boost/utility/string_view.hpp>
#include <deque>

namespace io = boost::iostreams;

using boost::string_view;

auto map_entries(string_view input) {
    std::deque<string_view> pairs;

    while (!input.empty()) {
        size_t pos = input.find('\n');

        if (pos != string_view::npos)
            pos = input.find('\n', pos + 1);

        if (pos != string_view::npos)
            pairs.push_back(input.substr(0, pos));

        input.remove_prefix(pos + 1); // safe with unsigned wrap around
    }

    return pairs;
}

#include <iostream>

int main() {
    io::mapped_file_source file("input.txt");

    auto data = map_entries({ file.data(), file.size() });

    std::stable_sort(data.begin(), data.end());

    for (auto entry : data)
        std::cout << entry << "\n";
}

打印

& AAAAAAB 
is
& AAABBAB
this
& BABABAB
text
& BBBBBA
example
& BCAAAA
an

¹使用POSIX mmap代替那里的助推器是微不足道的 ²如果编译器/库足够新,可以使用std::[experimental::]string_view