如何确定(升序)排序后数组中的原下标?

sagegz 2009-03-22 09:56:24
例如:一个整型数组a[]={1,3,3,5,7,4,2,6,8};
排序(升序)后:a[]={1,2,3,3,4,5,6,7,8};
排序前下标为: 0 1 2 3 4 5 6 7 8
排序后原下标为:0 6 1 2 5 3 7 4 8或0 6 2 1 5 3 7 4(求出任意一个即可)
大家有什么好的方法将排序后的原数组中元素的下标放进一个数组中呢?
...全文
2099 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
DrugScropion 2011-05-26
  • 打赏
  • 举报
回复
感谢了 用到了这个算法
zhoumeng1234 2011-05-14
  • 打赏
  • 举报
回复
请问能用MATLAB编写吗?
skyctr 2009-04-24
  • 打赏
  • 举报
回复
路过 学习
baihacker 2009-03-23
  • 打赏
  • 举报
回复
#include <stdio.h>

int main(void)
{
int a[]={1,3,3,5,7,4,2,6,8};
int temp[100] = {0};
int result[100];
int n = sizeof(a)/sizeof(a[0]);
int i;
for (i = 0; i < n; ++i) ++temp[a[i]];
for (i = 1; i < 100; ++i) temp[i] += temp[i-1];
for (i = 0; i < n; ++i) result[--temp[a[i]]] = i;
for (i = 0; i < n; ++i) printf("%d ", result[i]);
return 0;
}
elmnd 2009-03-23
  • 打赏
  • 举报
回复
难得的沙发。。。
PS:交换那里貌似用异或代替中间变量比较好哇。。。
zhh157 2009-03-23
  • 打赏
  • 举报
回复
做了一个stl特化版本的
如果对效率要求不是很高,可以考虑使用

#include <iostream>
#include <map>
#include <vector>
#include <cstdlib>

using namespace std;

struct MakePair
{
pair<int, int> operator() ( int n )
{
static int index = -1;
index++;
return pair<int, int>( n, index );
}
};


// return original order vector
vector<int> SortVector( vector<int>& vec )
{
multimap<int, int> myMap;
vector<int> vecOriginalIndex;
static int index = -1;

// insert multimap and add index tag
transform( vec.begin(), vec.end(), inserter( myMap, myMap.begin() ), MakePair() );

// sort
sort( vec.begin(), vec.end() );

multimap<int,int>::iterator map_iter;
vector<int>::iterator vec_iter = vec.begin();
for( ; vec_iter != vec.end(); ++vec_iter )
{
map_iter = myMap.find( *vec_iter );
vecOriginalIndex.push_back( map_iter->second );
myMap.erase( map_iter );
}

return vecOriginalIndex;
}

int main()
{
vector<int> vecTest;
vecTest.push_back( 2 );
vecTest.push_back( 8 );
vecTest.push_back( 4 );

cout<<"Original vector:";
copy( vecTest.begin(), vecTest.end(), ostream_iterator<int>( cout, " " ) );
cout<<endl;

vector<int> vecIndex = SortVector( vecTest );

cout<<"Sorted vector:";
copy( vecTest.begin(), vecTest.end(), ostream_iterator<int>( cout, " " ) );
cout<<endl;

cout<<"Original Index:";
copy( vecIndex.begin(), vecIndex.end(), ostream_iterator<int>( cout, " " ) );
cout<<endl;

system( "pause" );
return 0;
}
sagegz 2009-03-23
  • 打赏
  • 举报
回复
谢谢大家,自己用Java写了个函数.其实想用Java中的map写个,可是才发现Java基础很是薄弱...key-value都不太清楚.呵~!
有没有人秀下map的算法?这帖子暂时就不结了,等有人写出来后(包括偶自己哈)再结帖.
其实下面的跟结构体都差不多,就是转换数值的时候下标也同时转换.记得原来看过有人写过,不过没怎么细看,现在找也找不到了.所以只好自己写.
才发现很久没写过代码了...都是在帮别人改代码
呵呵~!

static void sort(int a[],int index[]) { //排序算法
int n = a.length;
for (int i = 0; i < n-1; i++)
for (int j = i+1; j <n ; j++)
if (a[i] > a[j]) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
int _temp = index[i];
index[i] = index[j];
index[j] = _temp;
}
}
xuedaoli 2009-03-23
  • 打赏
  • 举报
回复
二个数组或者一个结构体都能搞定了,再嫌麻烦就用map之类的搞下。

map<数值大小, 数值对应的原位置 >,按照数值大小排下序,再输出“数值对应的原位置”,搞定
beyond071 2009-03-23
  • 打赏
  • 举报
回复
学习了
sendto66 2009-03-23
  • 打赏
  • 举报
回复
ding
zhaohongbo83 2009-03-23
  • 打赏
  • 举报
回复
我觉得用两个并行数组就完全可以解决这个问题!
sagegz 2009-03-23
  • 打赏
  • 举报
回复
恩,19F写的挺好的.可以结帖了再次感谢大家~!
下面是19F的代码.

#include <iostream>
#include <map>
#include <vector>
#include <cstdlib>
#include <algorithm> //19F少个头文件,呵呵!

using namespace std;

struct MakePair
{
pair<int, int> operator() ( int n )
{
static int index = -1;
index++;
return pair<int, int>( n, index );
}
};


// return original order vector
vector<int> SortVector( vector<int>& vec )
{
multimap<int, int> myMap;
vector<int> vecOriginalIndex;
static int index = -1;

// insert multimap and add index tag
transform( vec.begin(), vec.end(), inserter( myMap, myMap.begin() ), MakePair() );

// sort
sort( vec.begin(), vec.end() );

multimap<int,int>::iterator map_iter;
vector<int>::iterator vec_iter = vec.begin();
for( ; vec_iter != vec.end(); ++vec_iter )
{
map_iter = myMap.find( *vec_iter );
vecOriginalIndex.push_back( map_iter->second );
myMap.erase( map_iter );
}

return vecOriginalIndex;
}

int main()
{
vector<int> vecTest;
vecTest.push_back( 2 );
vecTest.push_back( 8 );
vecTest.push_back( 4 );

cout<<"Original vector:";
copy( vecTest.begin(), vecTest.end(), ostream_iterator<int>( cout, " " ) );
cout<<endl;

vector<int> vecIndex = SortVector( vecTest );

cout<<"Sorted vector:";
copy( vecTest.begin(), vecTest.end(), ostream_iterator<int>( cout, " " ) );
cout<<endl;

cout<<"Original Index:";
copy( vecIndex.begin(), vecIndex.end(), ostream_iterator<int>( cout, " " ) );
cout<<endl;

system( "pause" );
return 0;
}
baihacker 2009-03-23
  • 打赏
  • 举报
回复
#include <cstdlib>
#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
int a[]={1,3,3,5,7,4,2,6,8};
int temp[100] = {0};
int result[100]; //下标
int n = sizeof(a)/sizeof(a[0]); //数组长
int i;
//赋值到临时数组
for (i = 0; i < n; ++i)
++temp[a[i]];
//数值重叠
for (i = 1; i < 100; ++i)
temp[i] += temp[i-1];

//上面求出了小于等于i的数的个数

//??俺不懂。。。
for (i = 0; i < n; ++i)
result[--temp[a[i]]] = i;

//--temp[a[i]]表示a[i]这个数排列后应该放的位置
//result[--temp[a[i]]] = i;
//表示应该上的位置上是原来第i个数

//输出下标
for (i = 0; i < n; ++i)
printf("%d ", result[i]);

system("PAUSE");
return EXIT_SUCCESS;
}
ch1oE 2009-03-23
  • 打赏
  • 举报
回复
若干年前,数据库刚诞生的时候,人们用链表
然后被要求排序,郁闷了,排序后index错掉了
怎么办?
然后人们有了对id的需求,每个记录都保持一个自始至终的唯一id
这样,只要id对了,排序后的index自然也可以找得到。

当然,简单讲就是两个链表
再简单讲就是滑动窗口的概念了。

以上这些都可以通过结构化的节点来实现 -- 数据库里面的一条记录。
xufei3085 2009-03-23
  • 打赏
  • 举报
回复
学习了,谢谢各位大大
elmnd 2009-03-23
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 baihacker 的回复:]
C/C++ code#include<stdio.h>intmain(void)
{inta[]={1,3,3,5,7,4,2,6,8};inttemp[100]={0};intresult[100];intn=sizeof(a)/sizeof(a[0]);inti;for(i=0; i<n;++i)++temp[a[i]];for(i=1; i<100;++i) temp[i]+=temp[i-1];for(i=0; i<n;++i) result[--temp[a[i]]]=i;for(i=0; i<n;++i) printf("%d", result[i]);return0;
}
[/Quote]
#include <cstdlib>
#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
int a[]={1,3,3,5,7,4,2,6,8};
int temp[100] = {0};
int result[100]; //下标
int n = sizeof(a)/sizeof(a[0]); //数组长
int i;
//赋值到临时数组
for (i = 0; i < n; ++i)
++temp[a[i]];
//数值重叠
for (i = 1; i < 100; ++i)
temp[i] += temp[i-1];
//??俺不懂。。。
for (i = 0; i < n; ++i)
result[--temp[a[i]]] = i;
//输出下标
for (i = 0; i < n; ++i)
printf("%d ", result[i]);

system("PAUSE");
return EXIT_SUCCESS;
}

那个循环不懂。。。
蜥蜴枪王 2009-03-22
  • 打赏
  • 举报
回复
o(∩_∩)o...1L的吧 很厉害啊 。。。
jakqigle 2009-03-22
  • 打赏
  • 举报
回复
如果觉得结构麻烦,那就并行两个数组啦
int num[]
int index[]
移动中:
num[i]...
相应index[i]....
但是需要是自己写排序算法 ^_^
jakqigle 2009-03-22
  • 打赏
  • 举报
回复
用一个结构为每个原始数组元素绑定其原下标。
lzy340623339 2009-03-22
  • 打赏
  • 举报
回复 1
方法1:用结构体数组,这个1楼连代码都贴了
方法2:定义一个和待排序数组A一样长度的数组B,存储的内容是0,1,2,...(下标)
然后在交换带排数组A中的元素时,用同样的下标交换B中的元素,这样就能同步了
加载更多回复(6)

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧