How to reverse a chain of characters?

无人久伴 提交于 2021-02-05 09:36:36

问题


I have to create a program that reverses phrases.

For example: when I write hello guys, I want syug olleh

This is what I have for the moment but I don't know how to reverse the characters in the board phraseT:

program reversing    
implicit none    
character(len=20),dimension(1:20)::phraseT    
character(len=20)::phrase,reverse    
integer::i,x


write(*,*)"write a phrase  :"    
read(*,'(a)')phrase    
x=len(trim(phrase))    
nomT(1:20)=" " 

do i=1,x    
nomT(i:i)=trim(phrase(i:i))    
end do

write(*,*)nomT    
end program reversing

回答1:


One simple way to do it ...

character(80) :: string = "Whatttt's up doc?"
character     :: temp
integer       :: i, length

write (*,*) string    ! Writes it out proper.
  length = len_trim(string) ! ignores trailing blanks. 
                            ! use len(string) to reverse those as well
  do i = 1, length/2
     temp = string(i:i)
     string(i:i) = string(length+1-i:length+1-i)
     string(length+1-i:length+1-i) = temp
  end do
write(*,*) string     ! Writes it out backwards.
end

Others will come up with more intelligent ones (and shorter) for sure.




回答2:


Here's a shorter way to do it:

forall (i=1:len(string)) string(i:i) = string(len(string)-i+1:len(string)-i+1)

It even saves a handful of bytes ! I'm not sure I'd suggest this was more intelligent though.




回答3:


Well, of course we want to be able to do this via a constant expression, so we attempt the following:

program reverse
   implicit none
   character(20), parameter :: input = 'Forward'
   integer i
   character(len(input)), parameter :: output = &
      transfer([(input(i:i),i=len_trim(input),1,-1)],trim(input))
   write(*,'("#",a,"#")') input, output
end program reverse

We get the same output with both gfortran and ifort:

#Forward             #
#drawroF#

I can't see what I might be doing wrong... is it the same bug in both compilers?




回答4:


@Rook's answer works for odd length of string too? Anyway here's my attempt, inspired by his answer which takes into account trailing blanks too:

    ! Reverse the string
    function reverse_string(string) result(gnirts)

        character(len=*) :: string
        character(len(string)) :: gnirts
        character(1) :: temp
        integer :: i, length

        length = len(string) 

        do i = 1,length
            gnirts(length-i+1:length-i+1) = string(i:i)
        end do

end function reverse_string



回答5:


Unlike arrays, characters don't have advanced ways of selecting "elements": substrings must be contiguous (which in particular excludes "reverse order"). The approaches of other answers here follow from that: using expressions which individually select length-1 substrings to build up a new string. An example would be a simple loop selecting matching substrings.

If we construct an array from individual substrings we can use transfer to put the re-ordered elements back as a string.

Similar to an array constructor implied loop we can use an I/O implied loop with internal write:

implicit none

character(*), parameter :: string = 'abcde'
character(len(string))  :: reverse
integer i

write(reverse,'(*(A))') (string(i:i),i=len(string),1,-1)

write(*,'(A)') string, reverse

end

This approach, however, cannot be used "in-place" (unlike the transfer one) as the internal file cannot appear in the I/O output item list. An intermediate variable could be used.



来源:https://stackoverflow.com/questions/64921392/how-to-write-character-variable-into-character-variable-in-reverse-order

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!