algorithm - 如何对嵌套类型的数组进行排序?
问题描述
我在 Fortran 95 中有以下数据结构:
type :: timestamp_record
integer :: year
integer :: month
integer :: day
integer :: hour
integer :: minute
integer :: second
end type
type :: foo_record
type(timestamp_record) :: timestamp
integer :: foo
integer :: bar
integer :: baz
end type
type(foo_record),dimension(10000) :: my_array
我想排序my_array
:
timestamp%year
timestamp%month
timestamp%day
timestamp%hour
timestamp%minute
timestamp%second
我已经看到有 qsort 和 qsort64 可用,但我不明白我应该使用什么作为长度。
我还看到需要提供比较功能(类似于 C qsort
)。
三个问题:
qsort
我在哪里可以找到为两个或三个字段实现的示例?- 即使在我想对嵌套数组进行排序的这种情况下,我也可以使用它
type
吗? type
结构在 Fortran 中称为 struct 吗?
解决方案
我无法评论您在哪里找到示例代码。这是题外话,但确实存在示例。使用我们搜索。试试 Github 或 RosettaCode 之类的网站。
但是,最好注意结构通常是如何排序的。您通常会创建一个比较函数来比较两个对象并说明它们应该如何排序,它们中的哪一个应该先行。
例如,从我的代码
function CompareWMPoints(Aptr,Bptr) bind(C,name="CompareWMPoints") result(res)
use iso_c_binding
integer(c_int) :: res
type(c_ptr),value :: Aptr,Bptr
type(WMPoint),pointer :: A,B
call c_f_pointer(Aptr,A)
call c_f_pointer(Bptr,B)
if ((A%xi+(A%yj-1)*Prnx+(A%zk-1)*Prnx*Prny) < (B%xi+(B%yj-1)*Prnx+(B%zk-1)*Prnx*Prny)) then
res = -1_c_int
else if ((A%xi+(A%yj-1)*Prnx+(A%zk-1)*Prnx*Prny) > (B%xi+(B%yj-1)*Prnx+(B%zk-1)*Prnx*Prny)) then
res = 1_c_int
else if (A%distx**2+A%disty**2+A%distz**2 < B%distx**2+B%disty**2+B%distz**2) then
res = -1_c_int
else if (A%distx**2+A%disty**2+A%distz**2 > B%distx**2+B%disty**2+B%distz**2) then
res = 1_c_int
else
res = 0_c_int
end if
end function CompareWMPoints
这比较了两个对象A
和B
。您可以引用嵌套在这两个对象中的任何其他结构。比较的结果是一个整数(-1、1 或 0)。
注意:A
andB
是通过 C 指针传递的,因为qsort()
使用了 C。使用 Fortran 排序子例程可以避免这种情况。可以使用type(...), intent(in) ::
,但如果类型不可互操作,这是不合法的。
因为我很懒,所以我只是qsort()
从 C 标准库中调用
interface
subroutine qsort(array,elem_count,elem_size,compare) bind(C,name="qsort")
import
type(c_ptr),value :: array
integer(c_size_t),value :: elem_count
integer(c_size_t),value :: elem_size
type(c_funptr),value :: compare !int(*compare)(const void *, const void *)
end subroutine qsort !standard C library qsort
end interface
但是您可以调用任何其他使用比较函数的子例程。
使用这些回调函数会带来一定的性能损失,但通常并不那么重要。
推荐阅读
- django - 检索指定主题的所有条目
- c - 从 C 环境执行 shell 命令并重定向输出
- objective-c - 在 Xcode 中使用 Objective-C 初始化 NSWindowController 时出现“缺少 setter 或实例变量”日志消息:
- javascript - 如何仅使用本地 json 文件或网络服务器中的 javascript 显示 json 数据?
- xamarin - 如何为 Xamarin Forms 中的特定页面使用不同的主题?
- spring - 关于 HEADERS 的 Spring Integration HttpRequestExecutingMessageHandler 问题
- jquery - 当用户单击发送按钮时,从 twitter 引导模式传递值
- c# - Asp.Net MVC 5 测试 IoC + 依赖注入
- css - 如何在没有弹性盒的情况下使图像使用最佳空间量
- javascript - 无法使用 PHP 执行查询,其中相同的查询在 phpmyadmin 中可以正常工作