使用String.substring进行SML递归编程

时间:2014-01-28 13:07:28

标签: recursion sml

我正在尝试编写一个带有两个字符串s1s2作为参数的程序。该函数应检查s2是否包含s1,如果包含s2,程序应在s1中写出String.substring(s2, size s2 - size s1, size s1) = s1的第一个字母的位置。

我想查看:(size s2 - 1)。 然后我需要在s2上进行递归,以便s1在每次比较后变小一个,从而将s2fun recurison 0 = 0 | recurison n = n + (n - 1) ”与String.substring一个字母进行比较。左

我对递归没有问题,如:

{{1}}

但是,当我与其他功能或{{1}}互动时,它会感到凌乱。当我想写一些递归的东西时,我该怎么想?你能给我一个关于这个问题的暗示吗?我喜欢自己提出解决方案,但需要帮助指出正确的道路。

1 个答案:

答案 0 :(得分:3)

首先,功能String.isSubstring : string -> string -> bool已经完成了您想要的功能。但是,由于您有兴趣以递归方式实现此类功能,因此您只需要考虑以下事项:

  1. 什么是基本情况(即,递归何时结束)?
  2. 步骤是什么(例如,如何从较小的解决方案中获得解决方案)?
  3. 因为在你的描述中你开始从右边检查子串然后向左移动,所以基本情况是你到达最左边的位置(即0)。对于步骤案例,在您检查了位置i后,您必须检查位置i - 1

    首先,您可以从处理检查位置i的情况的函数开始。

    fun substringat s1 s2 i =
      if size s1 + i > size s2 then false
      else String.substring (s2, i, size s1) = s1;
    

    然后是递归的骨架

    fun substringfrom s1 s2 i =
      if i < 0 then ~1
      else if substringat s1 s2 i then i
      else substringfrom s1 s2 (i - 1);
    

    最后,我们适当地初始化所有内容

    fun substring s1 s2 = substringfrom s1 s2 (size s2 - 1);
    

    为了避免一些不必要的检查,我们可以将所有这些结合起来

     fun substring s1 s2 =
       let
         val l1 = size s1;
         val l2 = size s2;
    
         fun substringat s1 s2 i =
           if l1 + i > l2 then false
           else String.substring (s2, i, l1) = s1;
    
         fun substringfrom s1 s2 i =
           if i < 0 then ~1
           else if substringat s1 s2 i then i
           else substringfrom s1 s2 (i - 1);
       in
         substringfrom s1 s2 (l2 - 1)
       end