数据排序
本帖最后由 Kieran 于 2023-6-19 10:15 编辑大家好,
我有一个数据文件。内容如下。 116
Parameter
0.2951429939E+02 0.0000000000E+00 0.0000000000E+00
0.0000000000E+00 0.1500000000E+02 0.0000000000E+00
0.0000000000E+00 0.0000000000E+00 0.2510000038E+02
Parameter
0.000000000 0.500000000 0.300000012
0.041669998 0.500000000 0.328289986
0.041669998 0.500000000 0.384860009
0.000000000 0.500000000 0.413150012
0.000000000 0.500000000 0.469720006
0.041669998 0.500000000 0.498010010
0.041669998 0.500000000 0.554579973
0.000000000 0.500000000 0.582870007
0.083329998 0.500000000 0.300000012
0.125000000 0.500000000 0.328289986
0.125000000 0.500000000 0.384860009
0.083329998 0.500000000 0.413150012
0.083329998 0.500000000 0.469720006
0.125000000 0.500000000 0.498010010
。。。。。。我想重排各行的位置。重排标准是,先按每行中的第一数据,由小到达排列。如果有两行,或者多行的第一个数据相等,则按第二个数据由小到大重排这些行的位置。如果有两行,或者多行第二个数据也相等,则按第三个数据重排各行位置。这是我的代码。PROGRAM COMPAIMPLICIT NONE
INTEGER, PARAMETER :: dp = SELECTED_REAL_KIND(15,14)
INTEGER :: i, j, k, l
REAL (KIND=dp) :: ap(116,6), lr(3,3), pl(3), ns(2,116)
OPEN (UNIT=3, FILE='data.dat', STATUS='OLD')
READ (UNIT=3, FMT=*)
READ (UNIT=3, FMT=*)
DO i = 1, 3, 1
READ (UNIT=3, FMT=*) pl
lr(i,:) = pl
END DO
READ (UNIT=3, FMT=*)
DO i = 1, 116, 1
READ (UNIT=3, FMT=*) pl
ap(i,4:6) = pl
ns(:,i) = i
END DO
DO i = 1, 116, 1
ap(i,1) = ap(i,4)*lr(1,1)+ap(i,5)*lr(2,1)+ap(i,6)*lr(3,1)
ap(i,2) = ap(i,4)*lr(1,2)+ap(i,5)*lr(2,2)+ap(i,6)*lr(3,2)
ap(i,3) = ap(i,4)*lr(1,3)+ap(i,5)*lr(2,3)+ap(i,6)*lr(3,3)
END DO
DO i = 2, 116, 1
DO j = 1, i-1, 1
IF ((ap(i,1) < ap(j,1)) .OR. &
((ap(i,1) == ap(j,1)) .AND. (ap(i,2) < ap(j,2))) .OR. &
((ap(i,1) < ap(j,1)) .AND. (ap(i,2) == ap(j,2)) .AND. &
(ap(i,3) < ap(j,3)))) THEN
k = ns(1,i)
DO l = j, i-1, 1
ns(1,l+1) = ns(1,l)
END DO
ns(1,j) = k
END IF
END DO
END DO
OPEN (UNIT=4, FILE='compare.dat', STATUS='UNKNOWN')
DO i = 1, 116, 1
DO j = 1, 116, 1
IF (ns(1,j) == i) WRITE (UNIT=4, FMT=*) ns(:,j), ap(j,1:3)
END DO
END DO
CLOSE (UNIT=3)
CLOSE (UNIT=4)
STOP
END PROGRAM COMPA
运行后,输出的重排结果如下。
1.0000000000000000 1.0000000000000000 0.0000000000000000 7.5000000000000000 7.5300004152000044 91.000000000000000 3.0000000000000000 1.2298607965527013 7.5000000000000000 9.6599863721468040
91.000000000000000 4.0000000000000000 0.0000000000000000 7.5000000000000000 10.370065458197006
91.000000000000000 5.0000000000000000 0.0000000000000000 7.5000000000000000 11.789972329093603
91.000000000000000 6.0000000000000000 1.2298607965527013 7.5000000000000000 12.500051440243805
91.000000000000000 7.0000000000000000 1.2298607965527013 7.5000000000000000 13.919957533040389
91.000000000000000 8.0000000000000000 0.0000000000000000 7.5000000000000000 14.630037397190604
91.000000000000000 9.0000000000000000 2.4594265091401013 7.5000000000000000 7.5300004152000044
92.000000000000000 2.0000000000000000 1.2298607965527013 7.5000000000000000 8.2400787733501950
93.000000000000000 11.000000000000000 3.6892874237500002 7.5000000000000000 9.6599863721468040
。。。。。。 很显然,这个排序时错误的,但我没找到程序里的错误。能麻烦大家帮我看下,我的代码哪里出了错误码?谢谢。
谢谢。
你的意思是不是用数组ns保存排序的序号,我大概修改了一下
! nline=116
DO i = 1, nline-1
write(*,'(2i4)')i;
ins=ns(1,i); ! 数组排序序号,原始序号在ns(2,i)中
DO j = i+1, nline
jns=ns(1,j); ! 序号
IF ((ap(jns,1) < ap(ins,1)) .OR. &
((abs(ap(jns,1)-ap(ins,1))<1.0e-6) .AND. (ap(jns,2) < ap(ins,2))) .OR. &
((abs(ap(jns,1)-ap(ins,1))<1.0e-6) .AND. (abs(ap(jns,2)-ap(ins,2))<1.0e-6) .AND. (ap(jns,3) < ap(ins,3))) & ! TODO: 原来是<
) THEN
write(*,*)'swap ',i,j
ns(1,i) = jns
ns(1,j)=ins
ins=jns
cycle;
END IF
END DO
END DO
OPEN (UNIT=4, FILE='resu.txt')
DO i = 1, nline
WRITE (UNIT=4, FMT='(2i6,2x,10(f12.4,2x))') ns(1:2,i), ap(ns(1,i),1:3)
END DO
本帖最后由 Kieran 于 2023-6-20 12:06 编辑
necrohan 发表于 2023-6-20 10:02
你的意思是不是用数组ns保存排序的序号,我大概修改了一下
! nline=116
非常感谢你的回复。
我的代码确实是在用ns变量保存各行在排序后的新序号。
我想请教几个问题。
1.你的代码的比较方式,是将各行中”最小“的那一行放在序号变量ns中的最前面,然后再放第二小的,紧接着是第三小,第四小。。。以此类推。我的理解正确吗?
2.请问你的代码中的CYCLE命令作用是什么呢?可不可以不用这个命令呢?
3.请问你觉得我的代码中哪里出了错误呢?我一直没找到原因。
谢谢,望指教。
Kieran 发表于 2023-6-20 11:55
非常感谢你的回复。
我的代码确实是在用ns变量保存各行在排序后的新序号。
1、我能大概明白你的代码的意思,但是排序那里和我思路不一样,我参考你的方式按自己的思路写的,结果就是你说的那样,从小到大排列。
2、cycle是直接进行下一次循环,不执行endif后面的语句节省点时间,这里因为endif后面没有语句了,所以不用也可以。
3、如果读入的lr是单位矩阵,那么你的代码ap(i,1:3)和ap(i,4:6)是相同的,我是这么测试查看输出结果的。
你的代码我没太明白,但是31行那个ap(i,1)<ap(j,1)应该是==。
我印象中浮点数比较用==的容易出问题,我用的绝对值差判断。
你的代码34~36行我不明白为什么要对ns循环赋值,我理解ns数组保存的序号,直接调换就行。
输出排序结果那段循环,就是43~47行,我不明白一共就116行你为什么要嵌套2次,直接循环116次输出就行。 necrohan 发表于 2023-6-20 15:06
1、我能大概明白你的代码的意思,但是排序那里和我思路不一样,我参考你的方式按自己的思路写的,结果就 ...
谢谢你的回复和指点。
我原本想着用insertion sorting方法排序,但我可能自己没想清楚每个步骤,所以代码不合理。
我再仔细想想吧。
再次感谢。
页:
[1]