如何在 Fortran 中将一个字符串数组嵌套在另一个数组中

问题描述 投票:0回答:3

在我的计算方法课上,我们的作业问题是用Python脚本给出的,但是我的老师说只要我们能把它们翻译成我们选择的语言,我们就可以用我们选择的语言解决它们。我正在尝试学习 Fortran,所以这就是我的选择。

在我们的一个问题中,设置包含一个字符串列表列表,如下所示:

q = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', h']]

在尝试重写这个时,我遇到了一个问题。通常,我会定义一个像字符这样的类型,但是存储在每个位置的值不是字符,它们是整个其他数组。我的第一个想法是做类似的事情:

character(1) :: letters(3), arr1(3), arr2(3), arr3(2)
arr1 = ['a', 'b', 'c']
arr2 = ['d', 'e', 'f']
arr3 = ['g', 'h']
letters(1) = [arr1, arr2, arr3]

等等。然而,这不起作用,因为

letters
不期望三个数组,而是三个字符。

如何在

letters
中嵌套数组?我需要这样做,因为问题是我们索引里面的数组。

fortran fortran90
3个回答
3
投票

您必须将其作为包含可分配字符数组的派生类型数组来执行。 Fortran 没有数组数组的概念。

举个例子:

program test
    implicit none
    type ltype
        character, allocatable :: l(:)
    end type ltype
    type(ltype), allocatable :: letters(:)
    integer :: i
    
    letters = [ltype(['a','b','c']),ltype(['d','e','f']),ltype(['g'])]
    do i=1,size(letters)
        print *, letters(i)%l
    end do
    
    end program test

1
投票

Fortran 不能做锯齿状数组(数组的数组)。但是你可以做一个结构数组(用户类型),每个结构包含一个或多个数组。

@SteveLionel 的答案(当然)是正确的,我只是想在这里添加一个不同的例子,以备将来使用。

下面的模块将

vector
定义为
real
值的数组,将
matrix
定义为向量数组。

module mod_matrix
use, intrinsic :: iso_fortran_env
implicit none

type vector
    real, allocatable :: data(:)
end type

type matrix
    type(vector), allocatable :: data(:)
end type

contains

pure function create_lower_triangular(n) result(M)
! creates a new matrix object representing a lower triangular matrix.
! example below for n=4
!
! M = | 1.0                 |
!     | 2.0  3.0            |
!     | 4.0  5.0  6.0       |
!     | 7.0  8.0  9.0  10.0 |
!
! each row is stored as a vector object which wraps an array.
integer, intent(in) :: n
type(matrix) :: M
type(vector) :: row
integer :: i,j,k

allocate(M%data(n))
k = 1
do i=1, n
    row = vector([(real(k+j-1), j=1,i)])
    M%data(i) = row
    k = k + i
end do

end function

subroutine show_matrix(M)
! display the contents of the matrix row-by-row on the console
type(matrix), intent(in) :: M
integer :: i, n
n = size(M%data)
do i=1, n
    print '(*(g11.3,1x))', M%data(i)%data
end do
end subroutine

end module

上面的代码可以用作

type(matrix) :: trig
trig = create_lower_triangular(7)
call show_matrix(trig)

带输出

   1.00
   2.00        3.00
   4.00        5.00        6.00
   7.00        8.00        9.00        10.0
   11.0        12.0        13.0        14.0        15.0
   16.0        17.0        18.0        19.0        20.0        21.0
   22.0        23.0        24.0        25.0        26.0        27.0        28.0

附言。我认为您尝试在数值方法课上学习 Fortran 真是太棒了。


0
投票

目前尚不清楚阵列有多大以及将用它们做什么。其他答案中的方法是通用方法,但对于非常简单的字符串数组来说可能有点矫枉过正。

如果它是您显示的一个小数组,通常用于某些辅助目的,而不是用于重型数字的非常大的数组,并且如果您知道字符串的最大长度,则可以只使用 Fortran 字符串数组。

integer, parameter :: max_len = 3
character(max_len) :: letters(3) = [character(max_len) :: 'abc', 'def', 'gh']

do j = 1, size(letters)
  do i = 1, len(letters(j))
    print *, letters(i:i)(j)
  end do
end do

这可能会浪费一些内存(字符串的长度都相同,并以空格结尾)但设置起来非常容易,代码也很短。

© www.soinside.com 2019 - 2024. All rights reserved.