显示列表中项目的多次出现,sml
Show Multiple occurrences of items in a list, sml
我正在尝试显示列表中某个元素的所有多次出现的索引。
标准毫升
但我的代码显示空列表:(
这是我的代码:
fun index(item, xs,ys) =
let
fun index'(m, nil , ys) = (
SOME (ys) )
| index'(m, x::xr , ys) = if x = item then(
(ys @ [m]);
index'(m + 1, xr , ys)
)
else index'(m + 1, xr,ys)
in
index'(0, xs , ys)
end;
index(1,[1,2,1,4,5,1],[]);
你能帮帮我吗?
要事第一:
index
应该有两个参数;要查找的元素和要查找的列表。
累加参数属于辅助函数
- 总是生产
SOME
而从不生产NONE
是没有意义的。
让我们先解决这些问题。
fun index (item, xs) =
let
fun index'(m, nil , ys) = ys
| index'(m, x::xr, ys) = if x = item then(
(ys @ [m]);
index'(m + 1, xr , ys)
)
else index'(m + 1, xr,ys)
in
index'(0, xs, [])
end;
现在使用index
时不需要传递额外的累加器参数了。
也不能从 []
.
以外的其他内容开始
你的下一个主要问题是
(ys @ [m]);
index'(m + 1, xr , ys)
首先创建列表 ys @ [m]
,立即将其丢弃,然后生成结果 index'(m + 1, xr , ys)
,这正是 else
分支所做的。
即条件等价于
if x = item
then index'(m + 1, xr, ys)
else index'(m + 1, xr, ys)
因此,index'
等同于
fun index'(m, nil, ys) = ys
| index'(m, x::xr, ys) = index'(m + 1, xr, ys)
由于您始终传递原始 ys
,并且开始时是 []
,因此结果始终是 []
。
你需要做的是将扩展列表传递给递归,这样它就可以成为递归终止时的结果。
重命名累加器 ys
以使其目的更清楚:
fun index (item, xs) =
let
fun index'(i, nil, accumulator) = accumulator
| index'(i, x::xr, accumulator) = if x = item
then index' (i + 1, xr, accumulator @ [i])
else index' (i + 1, xr, accumulator)
in
index'(0, xs, [])
end;
这是低效的,因为要重复将一个元素追加到列表的后面。
逆向积累很常见,用完了再修正。
(这“感觉”效率低下,但事实并非如此。)
fun index (item, xs) =
let
fun index'(i, nil, accumulator) = List.reverse accumulator
| index'(i, x::xr, accumulator) = if x = item
then index' (i + 1, xr, i::accumulator)
else index' (i + 1, xr, accumulator)
in
index'(0, xs, [])
end;
我正在尝试显示列表中某个元素的所有多次出现的索引。
标准毫升
但我的代码显示空列表:(
这是我的代码:
fun index(item, xs,ys) =
let
fun index'(m, nil , ys) = (
SOME (ys) )
| index'(m, x::xr , ys) = if x = item then(
(ys @ [m]);
index'(m + 1, xr , ys)
)
else index'(m + 1, xr,ys)
in
index'(0, xs , ys)
end;
index(1,[1,2,1,4,5,1],[]);
你能帮帮我吗?
要事第一:
index
应该有两个参数;要查找的元素和要查找的列表。
累加参数属于辅助函数- 总是生产
SOME
而从不生产NONE
是没有意义的。
让我们先解决这些问题。
fun index (item, xs) =
let
fun index'(m, nil , ys) = ys
| index'(m, x::xr, ys) = if x = item then(
(ys @ [m]);
index'(m + 1, xr , ys)
)
else index'(m + 1, xr,ys)
in
index'(0, xs, [])
end;
现在使用index
时不需要传递额外的累加器参数了。
也不能从 []
.
你的下一个主要问题是
(ys @ [m]);
index'(m + 1, xr , ys)
首先创建列表 ys @ [m]
,立即将其丢弃,然后生成结果 index'(m + 1, xr , ys)
,这正是 else
分支所做的。
即条件等价于
if x = item
then index'(m + 1, xr, ys)
else index'(m + 1, xr, ys)
因此,index'
等同于
fun index'(m, nil, ys) = ys
| index'(m, x::xr, ys) = index'(m + 1, xr, ys)
由于您始终传递原始 ys
,并且开始时是 []
,因此结果始终是 []
。
你需要做的是将扩展列表传递给递归,这样它就可以成为递归终止时的结果。
重命名累加器 ys
以使其目的更清楚:
fun index (item, xs) =
let
fun index'(i, nil, accumulator) = accumulator
| index'(i, x::xr, accumulator) = if x = item
then index' (i + 1, xr, accumulator @ [i])
else index' (i + 1, xr, accumulator)
in
index'(0, xs, [])
end;
这是低效的,因为要重复将一个元素追加到列表的后面。
逆向积累很常见,用完了再修正。
(这“感觉”效率低下,但事实并非如此。)
fun index (item, xs) =
let
fun index'(i, nil, accumulator) = List.reverse accumulator
| index'(i, x::xr, accumulator) = if x = item
then index' (i + 1, xr, i::accumulator)
else index' (i + 1, xr, accumulator)
in
index'(0, xs, [])
end;