范围函数未通过所有测试

  • 本文关键字:测试 函数 范围 sml
  • 更新时间 :
  • 英文 :


我正在编写一个range函数,它应该返回指定范围内的整数列表。

range(2,12,3)应该返回列表[2,5,8,11]

范围(10 2 ~ 1)应该返回列表(10、9、8、7、6、5、4、3]

for range(2,12,3) this works:

fun range(start, stop, step) =
if start > stop then nil
else start::range(start+step, stop, step);

for range(10,2,~1):

fun range(start,stop,step) =
if start <= stop then nil
else start::range(start+step, stop, step);

但是,我需要一个函数来处理这两种情况。我已经尝试使用orelse和else if如下,但函数返回一个空列表。

orelse:

fun range(start, stop, step) =
if start > stop orelse start <= stop then nil
else start::range(start+step, stop, step);

else if:

fun range(start,stop,step) =
if start > stop then nil
else if start <= stop then nil
else start::range(start+step,stop,step);

两个方法都返回

val it = [] : int list

我认为这与在基本情况下使用nil有关,但我不知道为什么。

需要修改什么以使函数返回两个测试的预期输出?

谢谢

不比较stopstart,考虑stop - startstep的符号,
如果你仔细想想,你会发现只要你在范围内,符号是一样的。

fun sgn x = if x < 0 
then ~1 
else if x > 0 
then 1 
else 0;
fun range (start, stop, step) = if sgn(stop-start) = sgn(step)
then start :: range (start + step, stop, step)
else []

问题:

在你的两个解中,条件总是true,因为你要检查start是否小于、大于或等于stop,这在数学上对任何一对数字都是成立的。

解决方案:

您必须根据step的标志检查当前情况。

如果step为零,则不检查任何其他内容,因为创建步骤0的范围是不可能的。抛出异常是个不错的选择。

如果step为正,检查start是否小于stop。如果没有,请停止。

如果step为负,检查start是否高于stop。如果没有,请停止。

完整代码:

fun range(start,stop,step) =
if start = stop orelse
(start < stop andalso step < 0) orelse
(start > stop andalso step > 0) then nil
else start::range(start+step, stop, step);

相关内容

  • 没有找到相关文章

最新更新