Erlang 理解递归:递归地查找子字符串是否是字符串的前缀
Erlang Understanding recursion: Find if substring is prefix of string recursively
我想了解这个在字符串中查找前缀的实现,它的实现没有使用任何内置的列表函数,而是使用递归遍历字符串。
尝试:
checkStringPrefix([C|StringTail],[C|LookupTail]) ->
checkStringPrefix(StringTail,LookupTail);
checkStringPrefix(_,[]) ->
"***";
checkStringPrefix(_String,_Lookup) ->
"".
有效,该函数递归调用自身,将第一个字符与尾部分开。
调用示例:
1> stringUtil:checkStringPrefix("test xxxxx", "test").
"***"
2> stringUtil:checkStringPrefix("test xxxxx", "testtt").
[]
在两个不相等字符的情况下,将调用最后一个函数变体。
我不完全理解这个概念,我希望得到解释。我理解递归迭代的过程,我不明白为什么第二个变体在正确的时刻被调用。
考虑将单个字符串或空字符串作为参数传递时会发生什么:
- 传递
"a"
和 "a"
:这会调用 checkStringPrefix/2
的第一个子句,因为在其函数头中显式匹配两个参数的第一个元素,这也强制两个参数都不能是空列表。这个子句递归调用函数,因为两个参数都没有尾部,第二个函数子句被调用,因为第二个参数匹配空列表,所以结果是 "***"
.
- 传递
"a"
和 "b"
:这不会调用第一个子句,因为第一个元素不匹配,也不会调用第二个子句,因为第二个参数不匹配空列表。因此它调用了第三个子句,所以结果是 ""
.
- 传递
""
和""
:这不会调用第一个子句,因为两个参数都是空列表;它调用第二个子句,因为第二个参数匹配空列表,所以结果是 "***"
。事实上,由于第二个子句将其第一个参数视为无关紧要,因此即使第一个参数不为空,同样的分析也适用。
- 传递
""
和"a"
:这不会调用第一个子句,因为第一个参数为空,也不会调用第二个子句,因为第二个参数不为空,所以它调用第三个子句,结果是 ""
.
无论两个参数字符串的长度如何,这些都是每次调用的选择。
为了回答您关于何时调用第二个函数子句的具体问题,只要第二个参数为空列表,就会发生这种情况,因为函数头中该情况的特定匹配,并且该函数头也忽略了第一个参数。匹配按照声明的顺序进行;第一个函数子句要求两个参数都至少有一个元素,因此当第二个参数为空列表时,它无法匹配第一个子句,因此匹配第二个子句。
我想了解这个在字符串中查找前缀的实现,它的实现没有使用任何内置的列表函数,而是使用递归遍历字符串。
尝试:
checkStringPrefix([C|StringTail],[C|LookupTail]) ->
checkStringPrefix(StringTail,LookupTail);
checkStringPrefix(_,[]) ->
"***";
checkStringPrefix(_String,_Lookup) ->
"".
有效,该函数递归调用自身,将第一个字符与尾部分开。
调用示例:
1> stringUtil:checkStringPrefix("test xxxxx", "test").
"***"
2> stringUtil:checkStringPrefix("test xxxxx", "testtt").
[]
在两个不相等字符的情况下,将调用最后一个函数变体。 我不完全理解这个概念,我希望得到解释。我理解递归迭代的过程,我不明白为什么第二个变体在正确的时刻被调用。
考虑将单个字符串或空字符串作为参数传递时会发生什么:
- 传递
"a"
和"a"
:这会调用checkStringPrefix/2
的第一个子句,因为在其函数头中显式匹配两个参数的第一个元素,这也强制两个参数都不能是空列表。这个子句递归调用函数,因为两个参数都没有尾部,第二个函数子句被调用,因为第二个参数匹配空列表,所以结果是"***"
. - 传递
"a"
和"b"
:这不会调用第一个子句,因为第一个元素不匹配,也不会调用第二个子句,因为第二个参数不匹配空列表。因此它调用了第三个子句,所以结果是""
. - 传递
""
和""
:这不会调用第一个子句,因为两个参数都是空列表;它调用第二个子句,因为第二个参数匹配空列表,所以结果是"***"
。事实上,由于第二个子句将其第一个参数视为无关紧要,因此即使第一个参数不为空,同样的分析也适用。 - 传递
""
和"a"
:这不会调用第一个子句,因为第一个参数为空,也不会调用第二个子句,因为第二个参数不为空,所以它调用第三个子句,结果是""
.
无论两个参数字符串的长度如何,这些都是每次调用的选择。
为了回答您关于何时调用第二个函数子句的具体问题,只要第二个参数为空列表,就会发生这种情况,因为函数头中该情况的特定匹配,并且该函数头也忽略了第一个参数。匹配按照声明的顺序进行;第一个函数子句要求两个参数都至少有一个元素,因此当第二个参数为空列表时,它无法匹配第一个子句,因此匹配第二个子句。