使用数字占位符从文件中按字母顺序排序

时间:2014-05-01 01:54:31

标签: c++ sorting

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

有什么想法吗?

#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()

编辑:我在寻找:

该文件如下所示:

苹果 橙子 香蕉

我需要的是这个: Apple 1 香蕉3 橙2

4 个答案:

答案 0 :(得分:3)

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

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

示例:

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

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

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

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

答案 1 :(得分:1)

解决此问题的一种方法是将输入字符串和原始序号位置保持在一个对象中。然后仅基于对象的字符串部分进行排序,然后为每个对象发出字符串和原始序号位置。

例如,对于您的班级,您可以拥有:

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一起使用。有关详细信息,请参阅this reference以及如何执行此操作的示例。

这是一种方法:

#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 filename\n";
        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

答案 2 :(得分:0)

如果你的编译器支持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;
}

答案 3 :(得分: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;
}