【问题标题】:Sorting with two vectors用两个向量排序
【发布时间】:2009-07-15 02:58:31
【问题描述】:

我想知道是否有可能,例如,如果您有一个 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();}

【问题讨论】:

  • 您使用两个向量而不是更复杂的数据结构的任何特殊原因?
  • 从一本书中学习,这是练习的目的。甚至还没有了解地图或数组。

标签: c++ sorting


【解决方案1】:

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

vector<unsigned int> indices;

这只是对字符串/双精度数组的索引,然后对该数组进行排序(根据字符串数组中的值进行交换)。

【讨论】:

  • 不,我不会单独对每个对象进行排序。可能有太多的数据。不过,我对您的第二个想法很感兴趣,但是它如何同时索引字符串和双精度值呢?我不需要为此创建一个类吗?
  • 否 - 索引只是一个数字。这个想法非常可行。您创建一个 vector 索引;然后将自定义排序传递给比较 myDoubles[indices[i]] 而不是 indices[i] 的 std::sort。然后你会得到一个索引 [i] 的排序,这样 myDoubles[indices[i]] 来删除此间接。
【解决方案2】:

你可以创建一个辅助向量:

vector<unsigned int> indices;

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

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

【讨论】:

    【解决方案3】:

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

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

    如果您能在第一时间做对,复制/粘贴一个 10 行的快速排序并进行明显的修改将是您想要的最快的方法。


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

    【讨论】:

    • 正是我要建议的迭代器,除了我可能会忘记提及 zip,我要补充说,“我真的懒得去麻烦为您提供一个经过测试的示例实现”;-)
    【解决方案4】:

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

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

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

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

    【讨论】:

    • 嗯。如何以某种方式同步向量,以便一个索引发生的任何事情都会发生在另一个索引上。
    • 问题在于同步。 std::sort 不允许这样做,因此您必须实现自己的排序。
    • 嗯....我查看了 中的排序成员,看起来我无法从中借用任何东西。有什么想法吗?
    • 如果您真的想这样做,请实现快速排序,或者,如果性能不是问题,则使用冒泡排序,保持两个向量同步。
    • 好的,谢谢,听起来像是一个有趣的小迷你项目(我希望!)。
    猜你喜欢
    • 1970-01-01
    • 2020-04-30
    • 1970-01-01
    • 2015-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-09
    • 2018-04-19
    相关资源
    最近更新 更多