【问题标题】:SML recursive programming with String.substring使用 String.substring 进行 SML 递归编程
【发布时间】:2014-01-28 21:45:32
【问题描述】:

我正在尝试编写一个程序,它将两个字符串 s1s2 作为参数。该函数应检查s2 是否包含s1,如果包含,则程序应在s2 中写入s1 的第一个字母出现的位置。

我想检查一下:String.substring(s2, size s2 - size s1, size s1) = s1。 然后我需要对(size s2 - 1) 进行递归,以便s2 在每次比较后变小一个,从而将s2 的比较“移动s1”向左移动一个字母。

我对以下递归没有任何问题:

fun recurison 0 = 0
  | recurison n = n + (n - 1)

但是当我与其他功能或String.substring 交互时,感觉很混乱。当我试图写一些递归的东西时,我应该怎么想?你能给我一个关于这个问题的提示吗?我喜欢自己提出解决方案,但需要帮助来指出正确的道路。

【问题讨论】:

    标签: recursion sml


    【解决方案1】:

    首先,已经有函数String.isSubstring : string -> string -> bool 可以满足您的需求。但是由于您有兴趣自己递归实现这样的功能,您只需要考虑以下几点:

    1. 什么是基本情况(即递归何时结束)?
    2. 什么是 step-case(即如何从较小的解决方案中获得解决方案)?

    由于在您的描述中您开始从右侧检查子字符串然后向左移动,因此基本情况是您到达最左边的位置(即 0)。至于step-case,在你检查了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
    

    【讨论】:

      猜你喜欢
      • 2020-03-20
      • 1970-01-01
      • 2014-08-07
      • 1970-01-01
      • 2011-12-22
      • 2021-05-26
      • 2020-03-08
      • 2017-05-15
      • 2019-02-25
      相关资源
      最近更新 更多