1

在尝试了解有关排序算法和 F# 的更多信息时,我在 F# 中编写了一个插入排序。我完全是 F# 和函数式编程的菜鸟。

let insert (a: array<int>) i item =
    i = i - 1
    while i >= 0 && item < a.[i] do
        a.[i + 1] = a.[i]
        i = i - 1
    a.[i + 1] = item
    a

let sort (a: array<int>) =
    for i in 1 .. (a.Length - 1) do
        a = insert a i a.[i]
    a
let a = [|3; 4; 1; 3;|]
a = sort a
for i in a do
    printfn "%d" i

代码编译得很好,但是当我运行可执行文件时......

Unhandled Exception: System.IndexOutOfRangeException: Index was outside the boun
ds of the array.
   at Isort.insert(Int32[] a, Int32 i, Int32 item)
   at Isort.sort(Int32[] a)
   at <StartupCode$isort>.$Isort.main@()

该异常有点无益,因为它没有说明超出范围的异常在哪里......有没有办法在我的代码中修复这个错误?

4

1 回答 1

4

几条评论:

  • 默认情况下,F# 值是不可变的。如果要修改值,请将它们声明为mutable.
  • =是相等,而<-赋值给可变值。
  • 注意 F# 中的警告。在这种情况下,由于您忽略了比较值,因此会出现很多错误。

改进版:

let insert (a: int []) j item =
    let mutable i = j - 1
    while i >= 0 && item < a.[i] do
        a.[i + 1] <- a.[i]
        i <- i - 1
    a.[i + 1] <- item

let sort (b: int []) =
    let a = Array.copy b
    for i in 1 .. (a.Length - 1) do
        insert a i a.[i]
    a
let a = [|3; 4; 1; 3; 5; 6; 5|]
let a' = sort a
for i in a' do printfn "%d" i

为了清楚起见,我修改了一些变量的名称。此外,辅助函数insert可以返回unit,而sort最好返回一个新副本,而不是改变输入数组。

于 2012-08-15T18:18:56.573 回答