如何分隔中间有符号的字符串
How to separate a string with a sign in the middle
我正在编写需要获取二项式表达式的两个变量的代码。我想知道有没有办法把中间有符号的字符串分成两个子串
e.g. (x+y)^3 to var1=x and var2=y or (qwerty-asdf)^12 to var1=qwerty and var2=asdf
我试过这样做:
character(100) :: str, var
var=' '
do i=1,len(str)
if (((str(i:i) == "+") .or. (str(i:i) == "-")) .or. &
((str(i:i) >= "a") .and. (str(i:i) <= "z"))) &
var=trim(var)//trim(str(i:i))
end do
但是唯一被删除的字符是括号和幂。
我看待我的问题的另一种方式是,如果我知道符号所在的字符串长度,那么我可以这样做:
character(100) :: str, var
var=' '
do i=1,len(the_unknown_string_length)
if ((str(i:i) >= "a") .and. (str(i:i) <= "z")) &
var=trim(var)//trim(str(i:i))
end do
虽然,我也不知道如何才能得到符号出现的具体字符串长度。
我不会乱用循环 - 我会使用可用的内部函数。像
ijb@ijb-Latitude-5410:~/work/stack$ cat binom.f90
Program binom
Implicit None
Character( Len = 100 ) :: expression
Character( Len = : ), Allocatable :: var1, var2
Write( *, '( a )' ) 'Expression?'
Read ( *, '( a )' ) expression
Call split_it( expression, var1, var2 )
If( Len( var1 ) /= 0 .And. Len( var2 ) /= 0 ) Then
Write( *, '( a, a, t20, i0 )' ) 'Var1 = ', var1, Len( var1 )
Write( *, '( a, a, t20, i0 )' ) 'Var2 = ', var2, Len( var2 )
Else
Write( *, * ) 'No + or - in the string'
End If
Contains
Subroutine split_it( expression, var1, var2 )
Implicit None
Character( Len = * ), Intent( In ) :: expression
Character( Len = : ), Allocatable, Intent( Out ) :: var1
Character( Len = : ), Allocatable, Intent( Out ) :: var2
Integer :: split_pos
Integer :: paren_pos
split_pos = Scan( expression, '+-' )
If( split_pos /= 0 ) Then
var1 = Trim( Adjustl( expression( :split_pos - 1 ) ) )
paren_pos = Scan( var1, '(' )
var1 = Trim( Adjustl( var1( paren_pos + 1: ) ) )
var2 = Trim( Adjustl( expression( split_pos + 1: ) ) )
paren_pos = Scan( var2, ')' )
var2 = Trim( Adjustl( var2( :paren_pos - 1 ) ) )
Else
Allocate( Character( Len = 0 ) :: var1 )
Allocate( Character( Len = 0 ) :: var2 )
End If
End Subroutine split_it
End Program binom
ijb@ijb-Latitude-5410:~/work/stack$ gfortran --version
GNU Fortran (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ijb@ijb-Latitude-5410:~/work/stack$ gfortran -Wall -Wextra -fcheck=all -std=f2008 -g binom.f90
ijb@ijb-Latitude-5410:~/work/stack$ ./a.out
Expression?
(x+y)^3
Var1 = x 1
Var2 = y 1
ijb@ijb-Latitude-5410:~/work/stack$ ./a.out
Expression?
(qwerty-asdf)^12
Var1 = qwerty 6
Var2 = asdf 4
ijb@ijb-Latitude-5410:~/work/stack$ ./a.out
Expression?
( aag + fg ) ^98
Var1 = aag 3
Var2 = fg 2
ijb@ijb-Latitude-5410:~/work/stack$ ./a.out
Expression?
wibble
No + or - in the string
我正在编写需要获取二项式表达式的两个变量的代码。我想知道有没有办法把中间有符号的字符串分成两个子串
e.g. (x+y)^3 to var1=x and var2=y or (qwerty-asdf)^12 to var1=qwerty and var2=asdf
我试过这样做:
character(100) :: str, var
var=' '
do i=1,len(str)
if (((str(i:i) == "+") .or. (str(i:i) == "-")) .or. &
((str(i:i) >= "a") .and. (str(i:i) <= "z"))) &
var=trim(var)//trim(str(i:i))
end do
但是唯一被删除的字符是括号和幂。
我看待我的问题的另一种方式是,如果我知道符号所在的字符串长度,那么我可以这样做:
character(100) :: str, var
var=' '
do i=1,len(the_unknown_string_length)
if ((str(i:i) >= "a") .and. (str(i:i) <= "z")) &
var=trim(var)//trim(str(i:i))
end do
虽然,我也不知道如何才能得到符号出现的具体字符串长度。
我不会乱用循环 - 我会使用可用的内部函数。像
ijb@ijb-Latitude-5410:~/work/stack$ cat binom.f90
Program binom
Implicit None
Character( Len = 100 ) :: expression
Character( Len = : ), Allocatable :: var1, var2
Write( *, '( a )' ) 'Expression?'
Read ( *, '( a )' ) expression
Call split_it( expression, var1, var2 )
If( Len( var1 ) /= 0 .And. Len( var2 ) /= 0 ) Then
Write( *, '( a, a, t20, i0 )' ) 'Var1 = ', var1, Len( var1 )
Write( *, '( a, a, t20, i0 )' ) 'Var2 = ', var2, Len( var2 )
Else
Write( *, * ) 'No + or - in the string'
End If
Contains
Subroutine split_it( expression, var1, var2 )
Implicit None
Character( Len = * ), Intent( In ) :: expression
Character( Len = : ), Allocatable, Intent( Out ) :: var1
Character( Len = : ), Allocatable, Intent( Out ) :: var2
Integer :: split_pos
Integer :: paren_pos
split_pos = Scan( expression, '+-' )
If( split_pos /= 0 ) Then
var1 = Trim( Adjustl( expression( :split_pos - 1 ) ) )
paren_pos = Scan( var1, '(' )
var1 = Trim( Adjustl( var1( paren_pos + 1: ) ) )
var2 = Trim( Adjustl( expression( split_pos + 1: ) ) )
paren_pos = Scan( var2, ')' )
var2 = Trim( Adjustl( var2( :paren_pos - 1 ) ) )
Else
Allocate( Character( Len = 0 ) :: var1 )
Allocate( Character( Len = 0 ) :: var2 )
End If
End Subroutine split_it
End Program binom
ijb@ijb-Latitude-5410:~/work/stack$ gfortran --version
GNU Fortran (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ijb@ijb-Latitude-5410:~/work/stack$ gfortran -Wall -Wextra -fcheck=all -std=f2008 -g binom.f90
ijb@ijb-Latitude-5410:~/work/stack$ ./a.out
Expression?
(x+y)^3
Var1 = x 1
Var2 = y 1
ijb@ijb-Latitude-5410:~/work/stack$ ./a.out
Expression?
(qwerty-asdf)^12
Var1 = qwerty 6
Var2 = asdf 4
ijb@ijb-Latitude-5410:~/work/stack$ ./a.out
Expression?
( aag + fg ) ^98
Var1 = aag 3
Var2 = fg 2
ijb@ijb-Latitude-5410:~/work/stack$ ./a.out
Expression?
wibble
No + or - in the string