Fortran77 删除重复行

delete duplicate rows in Fortran77

我有一个 table 的文件,包含 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 的新手。

你打开和关闭原始文件的每一行,这非常慢!要加快速度,您可以使用 rewind

不过,主要问题是算法的复杂性:O(n^2) [您将每一行与其他每一行进行比较]。首先,我会保留一个唯一行列表,并与该列表进行比较。如果已列出新行,则丢弃它 - 如果没有,则它是一个新的唯一行。这会将复杂性降低到 O(n*m),(希望)m << n(m 是唯一行的数量)。对行进行排序可能会加快比较速度。

下一句是从 I/O 移到内存中!将完整的文件读入一个数组,或者至少将唯一行的列表保存在内存中。一个 50,000x119 双精度数组需要 ~45MB 的 RAM,所以我认为这应该是可行的 ;-) 在最后一步将结果写回一块。

第一个问题:为什么坚持使用 Fortran 77?自从 g95 和 gfortran 出现以来,没有真正的理由使用一个已经过时了 20 多年的标准。

去重的规范方法是对它们进行排序,去重,然后按原来的顺序输出。如果您使用良好的排序算法,例如快速排序或堆排序,这将为您提供 O(n log n) 性能。

补充说明:将程序中的幻数(如 119)放入 PARAMETER 语句也是一个好主意。