You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fortran读取两文件并输出相同值至新文件的实现求助

解决思路:从两个文件提取共同数值并写入新文件

嘿,我懂你遇到的麻烦了——用双重DO循环逐个比对数组元素的思路本身没问题,但要么是循环逻辑没捋顺导致匹配失效,要么数据量大的时候效率低到让人头疼。下面给你两种实用的实现方案,看你提到DO语句,我默认用Fortran来写示例,其他类似语言也可以参考这个逻辑:

方案1:排序+双指针法(高效且通用)

这种方法把时间复杂度从双重循环的O(n*m)降到O(n log n + m log m),适合大多数场景,尤其是数值可以排序的情况:

program extract_common_values
    implicit none
    integer, allocatable :: arr1(:), arr2(:), common_vals(:)
    integer :: i, j, count, n1, n2, u1, u2, u3
    character(len=25) :: f1 = "input1.txt", f2 = "input2.txt", f3 = "common_output.txt"

    ! 第一步:读取第一个文件的所有数值
    open(newunit=u1, file=f1, status="old", action="read")
    n1 = 0
    do
        read(u1, *, iostat=i)
        if (i /= 0) exit
        n1 = n1 + 1
    end do
    rewind(u1)
    allocate(arr1(n1))
    do i = 1, n1
        read(u1, *) arr1(i)
    end do
    close(u1)

    ! 第二步:读取第二个文件的所有数值
    open(newunit=u2, file=f2, status="old", action="read")
    n2 = 0
    do
        read(u2, *, iostat=i)
        if (i /= 0) exit
        n2 = n2 + 1
    end do
    rewind(u2)
    allocate(arr2(n2))
    do i = 1, n2
        read(u2, *) arr2(i)
    end do
    close(u2)

    ! 第三步:对两个数组排序
    call bubble_sort(arr1, n1)
    call bubble_sort(arr2, n2)

    ! 第四步:双指针找共同元素
    i = 1
    j = 1
    count = 0
    allocate(common_vals(min(n1, n2))) ! 预分配最大可能空间
    do while (i <= n1 .and. j <= n2)
        if (arr1(i) == arr2(j)) then
            count = count + 1
            common_vals(count) = arr1(i)
            ! 跳过重复元素(避免重复写入相同值)
            do while (i <= n1 .and. arr1(i) == common_vals(count))
                i = i + 1
            end do
            do while (j <= n2 .and. arr2(j) == common_vals(count))
                j = j + 1
            end do
        else if (arr1(i) < arr2(j)) then
            i = i + 1
        else
            j = j + 1
        end if
    end do

    ! 裁剪数组到实际匹配数量
    if (count > 0) then
        call move_alloc(common_vals, common_vals(1:count))
    else
        deallocate(common_vals)
    end if

    ! 第五步:写入结果文件
    open(newunit=u3, file=f3, status="replace", action="write")
    if (allocated(common_vals)) then
        do i = 1, count
            write(u3, *) common_vals(i)
        end do
    end if
    close(u3)

contains
    ! 冒泡排序子程序(如果需要更快的可以换成快速排序)
    subroutine bubble_sort(arr, len)
        integer, intent(inout) :: arr(:)
        integer, intent(in) :: len
        integer :: k, l, temp
        do k = 1, len-1
            do l = 1, len-k
                if (arr(l) > arr(l+1)) then
                    temp = arr(l)
                    arr(l) = arr(l+1)
                    arr(l+1) = temp
                end if
            end do
        end do
    end subroutine bubble_sort
end program extract_common_values

方案2:哈希集合法(适合大数据量,无需排序)

如果你的编译器支持Fortran 2008及以上的哈希集合(比如GCC的hash_map模块),这种方法的查找速度接近O(1),效率更高:

program common_values_hash
    use iso_fortran_env
    use hash_map_int ! 注意:不同编译器的哈希模块可能不同,需对应调整
    implicit none
    type(hash_map_type) :: value_map
    integer :: val, stat, u1, u2, u3
    character(len=25) :: f1 = "input1.txt", f2 = "input2.txt", f3 = "common_output.txt"

    ! 把第一个文件的数值存入哈希集合
    open(newunit=u1, file=f1, status="old", action="read")
    call value_map%init()
    do
        read(u1, *, iostat=stat) val
        if (stat /= 0) exit
        call value_map%put(val, .true.) ! 用数值当键,标记存在即可
    end do
    close(u1)

    ! 遍历第二个文件,检查数值是否在集合中,写入结果
    open(newunit=u2, file=f2, status="old", action="read")
    open(newunit=u3, file=f3, status="replace", action="write")
    do
        read(u2, *, iostat=stat) val
        if (stat /= 0) exit
        if (value_map%has_key(val)) then
            write(u3, *) val
            call value_map%remove(val) ! 避免重复写入同一个数值
        end if
    end do
    close(u2)
    close(u3)
    call value_map%destroy()
end program common_values_hash

关于你之前的问题

你说variable1(i)=variable2(j)无法正常工作,大概率是双重循环的逻辑没处理对。比如正确的基础循环写法应该是这样(虽然效率低,但逻辑没问题):

! 假设已经读取了variable1(n1)和variable2(n2)
do i = 1, n1
    do j = 1, n2
        if (variable1(i) == variable2(j)) then
            write(u3, *) variable1(i)
            exit ! 找到匹配后跳出内层循环,避免重复写入同一个值
        end if
    end do
end do

不过这种方法在数组元素多的时候会很慢,所以更推荐前面两种高效方案。

内容的提问来源于stack exchange,提问作者guitae

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:07:16