根据一个的排列对三个向量进行排序,并带有重复项。

Posted

技术标签:

【中文标题】根据一个的排列对三个向量进行排序,并带有重复项。【英文标题】:Sorting Three vectors based on the arrangement of one, with duplicates. 【发布时间】:2016-11-03 01:25:03 【问题描述】:
vector<int> reference = ages;
sort(ages.begin(),ages.end());
for (int i=0; i<20 ;++i)
    for (int j=0; j<20; ++j)
        if (ages[i]==reference[j])
            cout << setw(LongestString(names))<<names[j] <<setw(agewidth)<<ages[i]<<setw(probwidth)<<prob[j]<<endl;
        
    

所以我有一个三个向量,我想根据年龄对它们进行排序,然后重新排序。但是,各个时代都有重复,因此每当遇到这些重复时,它就会多次打印它们。有没有办法在不创建结构的情况下防止这种情况发生?

【问题讨论】:

【参考方案1】:

生成一个从 0 到 ages.size()-1 的索引向量。根据年龄对索引进行排序,可能使用 lambda 比较函数。然后根据排序后的索引向量对所有三个向量重新排序。这将使所有三个向量保持“同步”,而不管年龄是否存在重复。

如果您只是根据索引 sorted[i] = original[sorted_index[i]] 复制向量,则重新排序很简单。也可以进行就地重新排序,如下例所示,但这是一个鲜为人知的算法,如果这是家庭作业,我不知道学生应该在哪里知道这个算法或能够找到这个算法的例子。该算法基于这样一个事实,即一个排列可以被认为是一个循环序列:

http://en.wikipedia.org/wiki/Permutation#Cycle_notation

    std::vector <int> A;                // ages
    std::vector <std::string> N;        // names
    std::vector <int> Z;                // zip codes
    std::vector <size_t> I;             // indices

    // vectors A, N, Z are initialized here ...

    // initialize vector of indices
    for(size_t i = 0; i < A.size(); i++)
        I.push_back(i);
    // sort vector of indices according to A
    std::stable_sort(I.begin(), I.end(),
        [&A](size_t i, size_t j) return 
        A[i] < A[j];);
    // reorder A, N, Z in place also restore I back to 0 to size-1
    // time complexity is O(n)
    // every move places an element in its sorted position
    for(size_t i = 0; i < A.size(); i++)
        size_t j, k;
        int tA;                         // temp variables
        std::string tN;
        int tZ;
        if(i != I[i])
            tA = A[i];
            tN = N[i];
            tZ = Z[i];
            k = i;
            while(i != (j = I[k]))
                A[k] = A[j];
                N[k] = N[j];
                Z[k] = Z[j];
                I[k] = k;
                k = j;
            
            A[k] = tA;
            N[k] = tN;
            Z[k] = tZ;
            I[k] = k;
        
    

【讨论】:

但是考虑到向量名称中有多个值对应相同的年龄,我该如何防止重复值呢? @HowDoesOneR - 排序是否稳定(如 std::stable_sort)无关紧要,然后将保留原始的年龄排序。即使排序不稳定,它仍然会在重新排序期间保持三个向量同步。年龄重复不会导致其他向量中的重复值(除非其他向量中有单独的重复集)。 当我尝试将此代码与 SIZE=20 一起使用时,我遇到了分段错误?我是否使用了错误的尺寸? @HowDoesOneR - I[] 需要包含 0 到 SIZE-1 的值(顺序无关紧要)。如果您遇到困难,我可以发布一个更完整的示例。 @HowDoesOneR - 我更新了我的答案。这是作业吗?如果是这样,我不确定学生应该如何找到诸如就地重新排序或“根据重新排序”之类的算法。

以上是关于根据一个的排列对三个向量进行排序,并带有重复项。的主要内容,如果未能解决你的问题,请参考以下文章

C++:如何检测向量中的重复项并打印一份?

将数组存储在向量中并对元素进行排序[关闭]

Armadillo C++:根据其他两个向量对向量进行排序

根据关联的整数向量对字符串向量进行排序[重复]

如何根据已排序索引的向量对 std::set 索引进行排序?

我如何按类属性对C++向量数组进行排序[重复]