数组排序,还要原来值在排序结果中的位置

hlh2002 2008-06-18 06:41:19
请大侠指教,给个算法。
要求对数组中的值排序,然后输出原来值在排序中的位置。例如:
原来的数组值为:
A[0]=3
A[1]=4
A[2]=2
A[3]=0
A[4]=6
要求排序的时候,去掉0值。从1算起。输出结果如下: 
A[0]=2 
A[1]=3
A[2]=1
A[3]=0
A[4]=4

请指教!谢谢!
...全文
307 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
僵哥 2009-05-13
  • 打赏
  • 举报
回复
我挖
YFLK 2008-06-19
  • 打赏
  • 举报
回复
建议楼主用堆排序方法,有现成的代码,你只要简单地修改一下,核心思路是:
1、对你的数据作一个辅助数组,用做原始数据和顺序号,
2、用排序程序对原数据进行排序,当有数组元素需要交换时,顺序号数据也同时进行交换。
3、最后的结果是原始数据数组是排序后的结果,顺序号数组中则是你需要的。
喝口水 2008-06-19
  • 打赏
  • 举报
回复
个人感觉,如果你要名次的话,我马上就给你弄出来了,可你说的这种输出结果,让人摸不着头脑,不知你到底要什么样的结果
喝口水 2008-06-19
  • 打赏
  • 举报
回复
最后一个输出的为啥是2,把所有重复的放到最后吗?
hlh2002 2008-06-19
  • 打赏
  • 举报
回复
flychenjun:忽略了一种情况,重复数据要排在同一个位次。
hlh2002 2008-06-19
  • 打赏
  • 举报
回复
如何0不参加排序和不能重复,那你以
myarr[0]:=3;
myarr[1]:=0;
myarr[2]:=5;
myarr[3]:=9;
myarr[4]:=5;
为例子,说一下结果输出结果应该是什么
1
0
2
3
2
喝口水 2008-06-19
  • 打赏
  • 举报
回复
如何0不参加排序和不能重复,那你以
myarr[0]:=3;
myarr[1]:=0;
myarr[2]:=5;
myarr[3]:=9;
myarr[4]:=5;
为例子,说一下结果输出结果应该是什么
DumDum 2008-06-19
  • 打赏
  • 举报
回复

procedure TForm1.Button1Click(Sender: TObject);
var
tmp1 : array of array[1..2] of integer; //原来有数据,利用二维数组记录数据及下标
tmp2 : array of array[1..2] of integer; //排序后数据,利用二维数组记录数据新下标
i,j:integer;
t,t1:integer;
begin
if Memo1.Lines.Count <=0 then exit;
SetLength( tmp1, Memo1.Lines.Count); //按Memo1.Lines.Count设置数组长度
SetLength( tmp2, Memo1.Lines.Count);
for i:=0 to Memo1.Lines.Count-1 do //利用Memo1进行数据初始化tmp1,tmp2
begin
tmp1[i,1] := strtoint(Memo1.Lines[i]);
tmp1[i,2] := i;
tmp2[i,1] := strtoint(Memo1.Lines[i]);
tmp2[i,2] := i;
end;
for i:= Memo1.Lines.Count-1 downto 0 do //利用冒泡法进行排序
begin
for j:=0 to i do
begin
if tmp2[j,1]=0 then continue ; //进行比较时,若比较值为0则不进行排序
if tmp2[j+1,1]=0 then //进行比较时,被比较值为0时则与下一个被比较值进行比较
begin
if tmp2[j,1] > tmp2[j+2,1] then ]; // 比较值的大小
begin
t := tmp2[j,1];
t1 := tmp2[j,2];

tmp2[j,1] := tmp2[j+2,1 //进行冒泡
tmp2[j+2,1] := t ;

tmp2[j,2] := tmp2[j+2,2]; //同时更换下标
tmp2[j+2,2] := t1;
end ;
end
else //若比较值和被比较值都不为0则进行比较
begin
if tmp2[j,1] > tmp2[j+1,1] then //同上
begin
t := tmp2[j,1];
t1 := tmp2[j,2];

tmp2[j,1] := tmp2[j+1,1]; //同上
tmp2[j+1,1] := t ;

tmp2[j,2] := tmp2[j+1,2];//同上
tmp2[j+1,2] := t1;
end;
end;
end;
end;

for i:= 0 to Memo1.Lines.Count-1 do
begin
Memo2.Lines.Add(inttostr(tmp2[i,1])+','+inttostr(tmp2[i,2]) );//输出排序后数据,
tmp1[tmp2[i,2],2] := i; //反向查找原有数据在排序后数据中的下标
end;

for i:= 0 to Memo1.Lines.Count-1 do
begin
Memo3.Lines.Add(inttostr(tmp1[i,1])+','+inttostr(tmp1[i,2]) ); //输出原有数据在排序后的下标
end;


end;
hlh2002 2008-06-19
  • 打赏
  • 举报
回复
我的算法已经出来了,就是觉得太复杂了。
想看看有没有更简单的算法,开拓思路。
僵哥 2008-06-19
  • 打赏
  • 举报
回复
要学会“自力更生”,而不是依赖。
僵哥 2008-06-19
  • 打赏
  • 举报
回复
都已经告诉你如何写了,为什么还要帮你写呢?那你自己忙什么?谁那么有空?
hlh2002 2008-06-19
  • 打赏
  • 举报
回复
Unsigned,这样的描述简明扼要,给个算法?
僵哥 2008-06-19
  • 打赏
  • 举报
回复
说白了,就是不改变位置进行排名.
把单列表变成双列表,不就好了?

另外也不能说是重复数据不参与排序,只是顺序保持。

比如第一名有两个99,你不能说是把某一个给去掉,除非你记作:
分数=99,名次=1
hlh2002 2008-06-19
  • 打赏
  • 举报
回复
hys_427 ,您的例子的输入结果应该是:
2,1,4,5,3

数据:
myarr[0]:=3;
myarr[1]:=2;
myarr[2]:=7;
myarr[3]:=9;
myarr[4]:=5;
排序后的结果是:2,3,5,7,9
我要的结果是:
3在排序后的序列中在第2位
2在排序后的序列中在第1位
7在排序后的序列中在第4位
9在排序后的序列中在第5位
5在排序后的序列中在第3位

其中要考虑重复数据和0的情况,0不参加排序。


不知道这样是否说明白了?           
喝口水 2008-06-18
  • 打赏
  • 举报
回复
不知你是不是要的排序后的下标,简单做了一下
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
myarr:array[0..4] of byte;
implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
myarr[0]:=3;
myarr[1]:=2;
myarr[2]:=7;
myarr[3]:=9;
myarr[4]:=5;
end;

procedure TForm1.Button1Click(Sender: TObject);
type
ARec=record
value,po:integer;
end;
var
Arr:array of ARec;
ResultArr:array of ARec;
temp:ARec;
i,j:integer;
begin
SetLength(arr,length(myarr));
SetLength(resultarr,length(myarr));
for i:=low(myarr) to high(myarr) do
begin
arr[i].value:=myarr[i];
arr[i].po:=i;
end;
for i:=low(arr) to high(arr)-1 do
for j:=low(arr) to high(arr)-1 do
if arr[j].value>arr[j+1].value then
begin
temp:=arr[j];
arr[j]:=arr[j+1];
arr[j+1]:=temp;
end;

for i:=low(arr) to high(arr) do
memo1.Lines.Add('值:'+inttostr(arr[i].value)+' 下标:'+inttostr(arr[i].po));
setlength(arr,0);
setlength(resultarr,0);
end;

end.
喝口水 2008-06-18
  • 打赏
  • 举报
回复
没看懂啥意思,看你那个输出结果并没有排序呀

16,748

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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