【问题标题】:How does one rank an array (sort) by value? *With a twist*如何按值对数组进行排序(排序)? *有一个转折*
【发布时间】:2010-09-06 00:32:00
【问题描述】:

我想使用C/C++ 对数组进行升序排序。结果是一个包含元素索引的数组。每个索引都对应于排序数组中的元素位置。

示例

Input:  1, 3, 4, 9, 6
Output: 1, 2, 3, 5, 4

编辑: 我正在使用 shell 排序程序。重复值索引是根据原始数组中首先出现的重复值来任意选择的。

更新:

尽管我尽了最大努力,但我仍然无法为指针数组实现排序算法。当前示例无法编译。

谁能告诉我怎么了?

非常感谢您的帮助!

void SortArray(int ** pArray, int ArrayLength) 
{
    int i, j, flag = 1;    // set flag to 1 to begin initial pass
    int * temp;    // holding variable orig with no *
    
    for (i = 1; (i <= ArrayLength) && flag; i++)
    {
        flag = 0;
        for (j = 0; j < (ArrayLength - 1); j++)
        {
            if (*pArray[j + 1] > *pArray[j])    // ascending order simply changes to <
            { 
                &temp = &pArray[j];    // swap elements
                &pArray[j] = &pArray[j + 1];    //the problem lies somewhere in here
                &pArray[j + 1] = &temp;
                flag = 1;    // indicates that a swap occurred.
            }
        }
    }
};

【问题讨论】:

    标签: c++ c arrays sorting


    【解决方案1】:

    由于您使用的是 C++,所以我会这样做。 SortIntPointers 函数可以是任何排序算法,重要的部分是它根据指针指向的 int 对指针数组进行排序。完成后,您可以遍历指针数组并分配它们的排序索引,该索引最终将位于原始数组中的原始位置。

    int* intArray; // set somewhere else
    int arrayLen;  // set somewhere else  
    
    int** pintArray = new int*[arrayLen];
    for(int i = 0; i < arrayLen; ++i)
    {
        pintArray[i] = &intArray[i];
    }
    
    // This function sorts the pointers according to the values they
    // point to. In effect, it sorts intArray without losing the positional
    // information.
    SortIntPointers(pintArray, arrayLen);
    
    // Dereference the pointers and assign their sorted position.
    for(int i = 0; i < arrayLen; ++i)
    {
        *pintArray[i] = i;
    }
    

    希望这已经足够清楚了。

    【讨论】:

      【解决方案2】:

      好的,这是我在 C++ 中的尝试

      #include <iostream>
      #include <algorithm>
      
      struct mycomparison
      {
          bool operator() (int* lhs, int* rhs) {return (*lhs) < (*rhs);}
      };
      
      int main(int argc, char* argv[])
      {
          int myarray[] = {1, 3, 6, 2, 4, 9, 5, 12, 10};
          const size_t size = sizeof(myarray) / sizeof(myarray[0]);
          int *arrayofpointers[size];
          for(int i = 0; i < size; ++i)
          {
              arrayofpointers[i] = myarray + i;
          }
          std::sort(arrayofpointers, arrayofpointers + size, mycomparison());
          for(int i = 0; i < size; ++i)
          {
              *arrayofpointers[i] = i + 1;
          }
          for(int i = 0; i < size; ++i)
          {
              std::cout << myarray[i] << " ";
          }
          std::cout << std::endl;
          return 0;
      }
      

      【讨论】:

        【解决方案3】:

        创建一个新数组,其值从 0 增加到 n-1(其中 n 是要排序的数组的长度)。然后根据新数组中的值索引的旧数组中的值对新数组进行排序。

        例如,如果您使用冒泡排序(易于解释),那么您不是比较新数组中的值,而是比较旧数组中由新数组中的值索引的位置处的值:

        function bubbleRank(A){
          var B = new Array();
          for(var i=0; i<A.length; i++){
            B[i] = i;
          }
          do{
            swapped = false;
            for(var i=0; i<A.length; i++){
              if(A[B[i]] > A[B[i+1]]){
                var temp = B[i];
                B[i] = B[i+1];
                B[i+1] = temp;
                swapped = true;
              }
            }
          }while(swapped);
          return B;
        }
        

        【讨论】:

          【解决方案4】:

          创建一个新数组并使用冒泡排序对元素进行排名

          int arr[n];
          int rank[n];
           for(int i=0;i<n;i++)
              for(int j=0;j<n;j++)
                 if(arr[i]>arr[j])
                   rank[i]++;
          

          每个元素的排名将是 rank[i]+1 到 1,2,....n 的顺序

          【讨论】:

            【解决方案5】:

            嗯,有一个简单的 n^2 解决方案。

            在python中:

            newArray = sorted(oldArray)
            blankArray = [0] * len(oldArray)
            for i in xrange(len(newArray)):
              dex = oldArray.index(newArray[i])
              blankArray[dex]  = i
            

            根据您的列表有多大,这可能有效。如果你的列表很长,你需要做一些奇怪的并行数组排序,这看起来并不好玩,而且是在你的代码中引入额外错误的快速方法。

            还要注意,上面的代码假定 oldArray 中的值是唯一的。如果不是这种情况,则需要进行一些后期处理来解决绑定值。

            【讨论】:

              【解决方案6】:

              使用 boost::lambda 对向量进行并行排序...

                 std::vector<int> intVector;
                 std::vector<int> rank;
              
                 // set up values according to your example...
                 intVector.push_back( 1 );
                 intVector.push_back( 3 );
                 intVector.push_back( 4 );
                 intVector.push_back( 9 );
                 intVector.push_back( 6 );
              
              
                 for( int i = 0; i < intVector.size(); ++i )
                 {
                    rank.push_back( i );
                 }
              
                 using namespace boost::lambda;
                 std::sort( 
                            rank.begin(), rank.end(),
                            var( intVector )[ _1 ] < var( intVector )[ _2 ] 
                          );
              
                 //... and because you wanted to replace the values of the original with 
                 //    their rank
                 intVector = rank;
              

              注意:我使用 vectorS 而不是数组,因为它更清晰/更容易,而且我使用了从 0 开始计数的 C 样式索引,而不是 1。

              【讨论】:

                【解决方案7】:

                这是c语言的解决方案

                #include <stdio.h>
                
                void swap(int *xp, int *yp) {
                    int temp = *xp;
                    *xp = *yp;
                    *yp = temp;
                }
                
                // A function to implement bubble sort
                void bubbleSort(int arr[], int n) {
                    int i, j;
                    for (i = 0; i < n - 1; i++)
                
                        // Last i elements are already in place
                        for (j = 0; j < n - i - 1; j++)
                            if (arr[j] > arr[j + 1])
                                swap(&arr[j], &arr[j + 1]);
                }
                
                /* Function to print an array */
                void printArray(int arr[], int size) {
                    for (int i = 0; i < size; i++)
                        printf("%d ", arr[i]);
                    printf("\n");
                }
                
                int main() {
                    int arr[] = {64, 34, 25, 12, 22, 11, 98};
                    int arr_original[] = {64, 34, 25, 12, 22, 11, 98};
                    int rank[7];
                
                    int n = sizeof(arr) / sizeof(arr[0]);
                    bubbleSort(arr, n);
                
                    printf("Sorted array: \n");
                    printArray(arr, n);
                
                    //PLACE RANK
                    //look for location of number in original array
                    //place the location in rank array
                    int counter = 1;
                    for (int k = 0; k < n; k++){
                        for (int i = 0; i < n; i++){
                            printf("Checking..%d\n", i);
                            if (arr_original[i] == arr[k]){
                                rank[i] = counter;
                                counter++;
                                printf("Found..%d\n", i);
                            }
                        }
                    }
                
                    printf("Original array: \n");
                    printArray(arr_original, n);
                
                    printf("Rank array: \n");
                    printArray(rank, n);
                    return 0;
                }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多