从带有数字占位符的文件中按字母顺序排序

Sorting alphabetically from file with numerical placeholder

本文关键字:顺序 排序 文件 数字 占位符      更新时间:2023-10-16

我有一个列表,我需要按字母顺序排序,而在这种情况下,我还需要保持它们的原始位置,因为列表最初是按时间顺序列出的。我已经把列表按字母顺序排序了,我不知道如何在时间位置添加。

有什么想法吗?

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
ifstream fin("prez.dat");
ofstream fout("sorted.dat");
void main()
{
    //fin.open("prez.dat");
    //fout.open("sorted.dat");
    vector<string> names;
    if(!fin.is_open())
    {
        cout << "Unable to open file..." << endl;
    }
    string word;
    while(getline(fin, word))
        names.push_back(word);
    sort(names.begin(), names.end());
    for (size_t i=0; i <names.size(); i++)
        cout << names[i] << 'n';
    system("pause");
}//End of void main()

编辑:我要查找的内容:

文件如下:

苹果橙色香蕉

我需要的是:苹果1香蕉3橙色2

我不确定我是否理解你到底想要什么。但我想你需要知道排序向量中每个元素的时间位置。

如果你的问题是这样的,那么答案太简单了。您可以创建一个新的int胜利者,它与胜利者的长度相同(例如10(,并包含从1到10的数字列表。当你对胜利者进行排序时,你必须对胜利者做出改变。现在只需对数字victor进行相同的更改,就可以知道每个元素的时间。

示例:

大型、汽车、应用程序1、2、3

当你对它们进行排序时,它们会是这样的:

应用程序,大,汽车3,1,2

但这样你就不能用这个函数来排序了,你必须自己写。

实现这一点的一种方法是将输入字符串和原始序数位置保持在对象中。然后仅根据对象的字符串部分进行排序,然后发出每个对象的字符串和原始序号位置。

例如,对于你的班级,你可以这样做:

class MyData {
private:
    std::string s;  // the string read from the file
    unsigned ord;   // original position of the string
public:
    // standard constructor
    MyData(std::string str, unsigned order) : s(str), ord(order) {}  
    // this allows you to use "std::cout << md;"
    friend std::ostream& operator<<(std::ostream& out, const MyData &m) {
        return out << m.s << ' ' << m.ord;
    }
    static bool cmp(const MyData &a, const MyData &b) {
        return a.s < b.s;
    }
};

然后,您只需要创建和推送对象,并定义一个与std::sort一起使用的比较操作。请参阅此参考资料以了解详细信息和如何执行该部分的示例。

这里有一种方法:

#include <algorithm>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
// MyData code goes here
int main(int argc, char *argv[]) {
    if (argc < 2) {
        std::cout << "Usage: sortfile filenamen";
        return 0;
    }
    std::vector<MyData> vec;
    std::string line;
    int i=1;
    for(std::ifstream in(argv[1]); std::getline(in, line); ++i) 
        vec.push_back(MyData(line, i));
    std::sort(vec.begin(), vec.end(), MyData::cmp);
    std::cout << "vec contains:n";
    for (auto md : vec)
        std::cout << md << 'n';
}

当编译(作为C++11(时,从这个输入文件,我称之为fruit.txt:

Apple
Orange
Banana

使用文件./sorted fruit.txt给出以下结果:

vec contains:
Apple 1
Banana 3
Orange 2

如果编译器支持lambda函数,则可以使用以下函数进行比较:

// sort vector by index using lambda compare function
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
int main()
{
    std::vector <std::string> names;
    std::vector <size_t> index;
    std::string fruits[5] = { "peach", "cherry", "apple", "plum", "banana" };
    for(size_t i = 0; i < sizeof(fruits) / sizeof(fruits[0]); i++){
        names.push_back(fruits[i]);
        index.push_back(i);
    }
    std::sort(index.begin(), index.end(), [&names](size_t i, size_t j)
        {return names[i] < names[j];});
    for(size_t i = 0; i < names.size(); i++){
        std::cout << "names[" << std::setw(2) << index[i] << "] = " <<
                     names[index[i]] << std::endl;
    }
    return 0;
}

如果编译器不支持lambda函数,可以将迭代器向量排序为字符串向量:

// sort vector of strings by vector of iterators to vector of strings
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
bool compare_strings_by_iterator(
        std::vector <std::string>::iterator i,
        std::vector <std::string>::iterator j)
{
    return *i < *j;
}
int main()
{
    std::vector <std::string> names;
    std::vector <std::string>::iterator it;
    std::vector <std::vector <std::string>::iterator> itv;
    std::string fruits[5] = { "peach", "cherry", "apple", "plum", "banana" };
    for(size_t i = 0; i < sizeof(fruits) / sizeof(fruits[0]); i++)
        names.push_back(fruits[i]);
    for(it = names.begin(); it < names.end(); it++)
        itv.push_back(it);
    std::sort(itv.begin(), itv.end(), compare_strings_by_iterator);
    for(size_t i = 0; i < names.size(); i++)
        std::cout << "name [" << std::setw(2) << itv[i] - names.begin() <<
                     "] " << *itv[i] << std::endl;
    return 0;
}