我有一个文件,它是一个由119个列(用空格分隔)和大约50000行(行)组成的表。我想删除重复的条目,即所有相同列(119)的行。我草拟了这段代码:
PROGRAM deldup
IMPLICIT NONE
DOUBLE PRECISION PAR(119),PAR2(119)
INTEGER I,J,K,LINE,TREP
CHARACTER filename*40
c Get the input file name
CALL getarg(1,filename)
c File where the results will be stored.
OPEN(29, FILE="result.dat", STATUS='UNKNOWN')
c Current line number
LINE=0
c counting repeated points
TREP=0
101 LINE=LINE+1
OPEN(27, FILE=filename, STATUS='OLD')
c Verifying that we are not in the first line... and we read the
c corresponding one
IF (LINE.NE.1) THEN
DO K=1,LINE-1
READ(27,11,ERR=103,END=9999)
END DO
ENDIF
READ(27,11,ERR=103,END=9999) (PAR(I),I=1,119)
c Start comparing line by line looking for matches. If a match is
c found , close the
c file and open it again to read the next line. If the end of file is
c reached and not iqual rows found, write the line in "results.dat"
102 READ(27, 11,END=104, ERR=102) (PAR2(I),I=1,119)
DO J=1,119
IF ( PAR(J).NE.PAR2(J) ) THEN
GOTO 102
ELSEIF (J.EQ.119) THEN
TREP=TREP+1
GOTO 103
ENDIF
END DO
104 WRITE(29,11) (PAR(I),I=1,119)
103 CLOSE(27)
GOTO 101
9999 WRITE(*,*) "DONE!,", TREP, "duplicated points found!"
CLOSE(27)
CLOSE(28)
CLOSE(29)
11 FORMAT(200E14.6)
END这实际上很有效,只是速度太慢了。为什么?有我可以用的图书馆吗?对不起,我的无知,我是全新的Fortran77。
发布于 2015-01-25 14:30:24
对于每一行您打开和关闭原始文件,这是非常缓慢的!为了加快速度,您只需使用rewind即可。
但是,主要的问题是算法的复杂性:将每一行与每一行进行比较的O(n^2)。首先,我将保留一个独特行的列表,并将其与该列表进行比较。如果一个新行已经列出,请丢弃它-如果不是,它是一个新的唯一行。这将降低O(n*m)的复杂性,(希望是) m << n (m是唯一行数)。对行进行排序可能会加快比较速度。
下一个评论是从I/O移到记忆!将完整的文件读入数组中,或者至少将唯一行的列表保存在内存中。一个50,000x119双精度数组需要大约45 of的RAM,所以我认为这应该是可行的;-)在最后一步中将结果完整地写回。
发布于 2015-01-25 15:46:07
第一个问题:为什么要坚持使用Fortran 77?自从g95和gfortran出现以来,没有真正的理由使用一个已经过时了20多年的标准。
删除重复的标准方法是对它们进行排序,删除重复项,然后按照原始顺序输出它们。如果您使用一个很好的排序算法,如快速排序或堆排序,这将使您具有O(n log )性能。
还有一点需要注意:将程序中的119这样的神奇数字放入参数语句中也是个好主意。
https://stackoverflow.com/questions/28137123
复制相似问题