根据索引和优先级对列表数进行排序

时间:2011-11-07 14:47:10

标签: c++ c shell sorting tcl

我有一个列表集合,每个列表包含大约6到7个值。像,

list1 = 2,4,7,4,9,5
list2 = 4,3,7.3,9,8,1.2
list3 = 2,2.4,7,9,8,5
list4 = 9,1.6,4,3,4,1
list5 = 2,5,7,9,1,4
list6 = 6,8,7,2,1,5
list7 = 4,2,5,2,1,3

现在我要对这些进行排序,其中index1为primary,index3为secondary,index2为secondary,依此类推。也就是说,输出应该是:

 2,2.4,7,9,8,5
 2,4,7,4,9,5
 2,5,7,9,1,4
 4,2,5,2,1,3
 6,8,7,2,1,5
 9,1.6,4,3,4,1

我希望首先为index1排序列表顺序,如果index1的值与index3相同,则在index3上进行排序,并且如果与index2相同。这里列表的数量较少,可以增加到20,索引也可以增长到20。

我想知道的算法与iTunes歌曲排序的算法相同,其中具有相同专辑的歌曲首先排序,然后按艺术家排序,然后排名,然后按名称排序。如果专辑的名称是相同的那就是专辑,那么如果相同,则按艺术家进行排序,然后按等级进行排序。代码可以在C / C ++ / tcl / shell中。

4 个答案:

答案 0 :(得分:3)

sort -n -t ',' -k 1 -k 3 -k 2

将列表作为单独的行添加到其中。

答案 1 :(得分:1)

您可以使用STL's sort,然后您所要做的就是编写一个能够达到您想要的效果的比较函数(链接中的示例应该足够好)。

答案 2 :(得分:1)

因为您要求提供Tcl解决方案:

set lol {
   {2 4 7 4 9 5}
   {4 3 7.3 9 8 1.2}
   {2 2.4 7 9 8 5}
   {9 1.6 4 3 4 1}
   {2 5 7 9 1 4}
   {6 8 7 2 1 5}
   {4 2 5 2 1 3}
}

set ::EPS 10e-6
proc compareLists {ixo e1 e2} {
   foreach ix $ixo {
      set d [expr {[lindex $e1 $ix] - [lindex $e2 $ix]}]
      if {abs($d) > $::EPS} {
         return [expr {($d>0)-($d<0)}]
      }
   }
   return 0
}

foreach li [lsort -command [list compareLists {0 2 1}] $lol] {
   puts $li
}

希望有所帮助。

答案 3 :(得分:0)

这是一个C ++解决方案:

#include <iostream>
#include <vector>
#include <algorithm>

template <typename Array, typename CompareOrderIndex>
struct arrayCompare
{
   private:
      size_t
         size ;
      CompareOrderIndex
        index ;
   public:

      arrayCompare( CompareOrderIndex idx ) :  size( idx.size() ), index(idx)  { }

      bool helper( const Array &a1, const Array &a2, unsigned int num ) const
      {
         if( a1[ index[size-num] ] > a2[ index[size-num] ] )
         {
            return false ;
         }

         if( !(a1[ index[size-num] ] < a2[ index[size-num] ]) )
         {
            if( 1 != num )
            {
               return helper( a1, a2, num-1 ) ;   
            }
         }

         return true ;
      }

      bool operator()(  const Array &a1, const Array &a2 ) const
      {
         return helper( a1, a2, size ) ; 

      }
} ;

int main()
{
   std::vector< std::vector<float> > lists = {     { 2, 4,   7,   4, 9, 5},
                                                   { 4, 3,   7.3, 9, 8, 1.2 },
                                                   { 2, 2.4, 7,   9, 8, 5 },
                                                   { 4, 2,   5,   2, 1, 3 },
                                                   { 9, 1.6, 4,   3, 4, 1 },
                                                   { 2, 5,   7,   9, 1, 4 },
                                                   { 6, 8,   7,   2, 1, 5 },
                                                   { 4, 2,   5,   2, 1, 1 },
                                                };
   //
   // Specify the column indexes to compare and the order to compare.
   // In this case it will first compare column 1 then 3 and finally 2.
   // 
   //std::vector<int> indexOrder = { 0, 2, 1, 3, 4 ,5  } ;
   std::vector<int> indexOrder = { 0, 2, 1  } ;

   arrayCompare< std::vector<float>, std::vector<int>> compV( indexOrder ) ;

   std::sort( lists.begin(), lists.end(), arrayCompare< std::vector<float>, std::vector<int>>( indexOrder )  ) ;

    for(auto p: lists) 
    {
       for( unsigned int i = 0; i < p.size(); ++i )
       {
          unsigned int idx = ( i > (indexOrder.size() -1) ? i : indexOrder[i] ) ;

          std::cout << p[idx] << ", " ;
       }
       std::cout << std::endl ;
    }
}