如何按值对数组进行排序(排序)? *有一个转折*
Posted
技术标签:
【中文标题】如何按值对数组进行排序(排序)? *有一个转折*【英文标题】: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.
;
【问题讨论】:
【参考方案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;
【讨论】:
以上是关于如何按值对数组进行排序(排序)? *有一个转折*的主要内容,如果未能解决你的问题,请参考以下文章