用两个向量排序

时间:2009-07-15 02:58:32

标签: c++ sorting

我想知道,如果您有vector<string>vector<double>对应的对,是否可以按字母顺序对vector<string>进行排序,同时保持对匹配。

我知道这可以通过创建一个包含两个值并只对它进行排序的类来完成,但我宁愿保留两个不同的向量。

有什么想法吗?

最终守则:

#include "std_lib_facilities.h"

struct Name_pairs
{
       vector<string>names;
       vector<double>ages;
       void quicksort(vector<string>& num, vector<double>& num2, int top, int bottom);
       int divide(vector<string>& array, vector<double>& array2, int top, int bottom);
       bool test();
       string read_names();
       double read_ages();
       void print();
};

string Name_pairs::read_names()
{
       string name;
     cout << "Enter name: ";
     cin >> name;
     names.push_back(name);
     return name;
}

double Name_pairs::read_ages()
{
     double age;
     cout << "Enter corresponding age: ";
     cin >> age;
     ages.push_back(age);
     cout << endl;
     return age;
}

int Name_pairs::divide(vector<string>& array, vector<double>& array2, int top, int bottom)
{
    string x = array[top];
    int i = top-1;
    int j = bottom+1;
    string temp;
    double temp2;
    do{
        do
        {
             j--;
             }while(x<array[j]);

        do
        {
             i++;
             }while(x>array[i]);

        if(i<j)
        {
               temp = array[i];
               temp2 = array2[i];
               array[i] = array[j];
               array2[i] = array2[j];
               array[j] = temp;
               array2[j] = temp2;
               }
               }while(i<j);
        return j;
}


void Name_pairs::quicksort(vector<string>& num, vector<double>& num2, int top, int bottom) // top is subscript of beginning of vector
{
     int middle;
     if(top < bottom)
     {
            middle = divide(num, num2, top, bottom);
            quicksort(num, num2, top, middle);
            quicksort(num, num2, middle+1, bottom);
            }
     return;
}

void Name_pairs::print()
{
     for(int i = 0; i < (names.size()-1) && i < (ages.size()-1); ++i)
             cout << names[i] << " , " << ages[i] << endl;
}

int main(){
    Name_pairs np;
    cout << "Enter names and ages. Use 0 to cancel.\n";
    bool finished = false;
    while(!finished){
    finished = "0" == np.read_names();
    finished = 0 == np.read_ages();}
    np.quicksort(np.names, np.ages, 0, (np.names.size()-2));
    np.print();
    keep_window_open();}

4 个答案:

答案 0 :(得分:5)

如果您自己手动对它们进行排序,则只需将双数组中的相应项目与通常执行的字符串数组中的项目交换即可。或者,您可以拥有第三个数组:

vector<unsigned int> indices;

只需索引到字符串/ double数组,然后对该数组进行排序(根据字符串数组中的值进行交换)。

答案 1 :(得分:3)

您可以创建辅助矢量:

vector<unsigned int> indices;

将其初始化为0,1,2,...n-1,其中n是向量的大小,并使用sort算法使用查看vector<string>的仿函数对其进行排序,也就是说,当要求比较index1和index2时,仿函数将查找相应的字符串并进行比较。排除indices后,您可以轻松地对两个数组进行排序,使其在线性时间内符合要求。

编辑:我没有看到Jim Buck的第二个建议。我的答案只是一个扩展版本。

答案 2 :(得分:3)

虽然索引的想法实际上是相同的,但事实上你可以定义一个知道两个向量的随机访问迭代器类型,并同步移动它们(通过赋值)。该迭代器的value_type将是pair。在函数式编程中,你称之为“zip”(但不是拉链)。

除非你在太空中非常紧张,否则绝对不值得麻烦。如果你有空间,实际上将两个向量压缩成单个向量对,或者使用索引方法,都更容易。

如果你能够在第一时间做到正确,那么通过明显的修改复制/粘贴10行快速排序将是你想要的最快方式。


Ed的说明: Boost中已经有一个已经写好的Zip Iterator,正如同一个问题的新答案所指出的那样: "Locking" two vectors and sorting them

答案 3 :(得分:2)

如果您打算使用std :: sort,则需要使用像对一样的数据结构。 当然,您可以手动对向量进行排序,并基本上重新实现std :: sort。

这个问题实际上取决于许多其他问题,例如:

  • 向量中有多少项?
  • 表现有多重要?
  • 你真的想要实现自己的排序算法吗?

实施快速排序应该相当轻松,并且可以避免移动数据。