abandon 发表于 2014-3-6 11:40:59

关于读取字符串(可能动态)和排序

本帖最后由 abandon 于 2014-3-6 11:48 编辑

Using names.txt (放在附件), a 46K text file containing over five-thousand first names, begin by sorting it into alphabetical order. Then working out the alphabetical value for each name, multiply this value by its alphabetical position in the list to obtain a name score.
For example, when the list is sorted into alphabetical order, COLIN, which is worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th name in the list. So, COLIN would obtain a score of 938 × 53             = 49714.
What is the total of all the name scores in the file?
就是所有名字按 ABCD 排序,然后得到他在ABCD排序中的位置,然后A是一分,B是两分这样加,然后乘以位置数,求和。
因为不知道里面具体有多少个名字,所以可能用到动态读取。自己是编程 菜鸟,fortran刚开始,希望那位好心的大神可以帮忙读取这个文件,最好是一个字符串数组,每个元素存一个名字。排序的话,要是有大神愿意提供代码更是感激不尽!!

楚香饭 发表于 2014-3-6 12:13:28

答案是
共5163个单词
总分   871198282

以下代码,分别使用了网站的两个函数:
GetDataN http://www.fcode.cn/code_gen-34-1.html
HeapSort http://www.fcode.cn/code_prof-2-1.html

program www_fcode_cn
implicit none
Integer , parameter :: LEN_ALL = 50000 !// 总长度
Integer , parameter :: LEN_ONE = 16 !// 单个长度
Character( Len = LEN_ALL ) :: cStrAll
Character( Len = LEN_ONE ) , allocatable :: cStrSplit( : )
integer :: n , sum , score !// 单词个数,总分,单个分
integer :: i
Open( 12 , File = "names.txt" )
Read( 12 , '(a50000)' ) cStrAll
Close( 12 )
n = GetDataN( cStrAll ) !// 获得单词数
write(*,'(a,i0,a)') '共',n,'个单词'
Allocate( cStrSplit(n) )
read( cStrAll , * ) cStrSplit
call HeapSort( cStrSplit , comp_f ) !// 排序
sum = 0
Do i = 1 , n
    sum = sum + i * GetStringScore( Trim(cStrSplit(i)) )
End Do
write( * , * ) '总分' , sum
Deallocate( cStrSplit )

contains

Integer Function GetStringScore( c )
    Character( Len = * ) :: c
    integer :: i
    GetStringScore = 0
    Do i = 1 , Len_Trim( c )
      GetStringScore = GetStringScore + ( ichar(c(i:i)) -ichar('A') + 1 )
    End Do
End Function GetStringScore

Integer Function GetDataN( cStr )
    Character( Len = * ) , Intent( IN ) :: cStr
    Integer :: i
    Logical :: bIsSeparator , bIsQuote
    GetDataN = 0
    bIsSeparator = .TRUE.
    bIsQuote = .FALSE.
    Do i = 1 , Len_Trim( cStr )
      Select Case( cStr(i:i) )
      Case( '"' , "'" ) !// 如果遇到引号
      If ( .Not.bIsQuote ) GetDataN = GetDataN + 1!//如果不在引号中,则增加一个数据
      bIsQuote = .Not.bIsQuote !// 引号结束或开始
      bIsSeparator = .FALSE.
      Case( " " , "," , char(9) ) !// 如果遇到分隔符
      If ( .Not.bIsQuote ) then!// 分隔符如果不在引号中
          bIsSeparator = .TRUE.
      End If
      Case Default      
      If ( bIsSeparator ) then
          GetDataN = GetDataN + 1
      End If
      bIsSeparator = .FALSE.
      End Select
    End Do
End Function GetDataN

Subroutine HeapSort( stD , comp_f )
    Character( Len = * ) , Intent( INOUT ) :: stD( : )
    Real , External :: comp_f
    Integer i,ir,j,l,n
    Character( Len = LEN_ONE ) :: stTemp
    n = size( stD )
    If ( n < 2 ) Return
    l = n / 2 + 1
    ir = n
    Do while( .TRUE. )
      If( l > 1 ) then
      l = l - 1
      stTemp = stD( l )
      Else
      stTemp = stD( ir )
      stD( ir ) = stD( 1 )
      ir = ir - 1
      If( ir == 1 ) then
          stD( 1 ) = stTemp
          return
      End If
      End If
      i = l
      j = l + l
      Do while( j<=ir )
      If( ( j < ir ) ) then
          If ( comp_f( stD(j) , std(j+1) ) > 0.0 ) then
            j = j+1
          End If
      EndIf
      If( comp_f( stTemp , stD(j) ) > 0.0 )then
          stD(i) = stD( j )
          i = j
          j = j + j
      Else
          j = ir + 1
      End If
      EndDo
      stD( i ) = stTemp
    End Do
End Subroutine HeapSort

Real Function comp_f( st1 , st2 )
    Character( Len = * ) , Intent( IN ) :: st1 , st2
    if ( Trim(st1) > Trim(st2) ) then
      comp_f = -1.0
    else
      comp_f = 1.0
    end if      
End Function comp_f

end program www_fcode_cn

Felix804665 发表于 2014-3-6 12:32:06

这个读写文件及文件处理我需要继续努力好好学习
页: [1]
查看完整版本: 关于读取字符串(可能动态)和排序