在两个列表之间查找公共元素时发生groovy错误



我有这个代码:

def input1 = ['a','b','e','r','t']
input2 = ['v','n','m','y']
ans = []
def common(def element,def i) {
  if (element == input2[i]) {
    ans << element
    return
  } else {
    common(element,++i)
  }
}  
for (i=0;i<input1.size();i++) {
  common(input1[i],0)
}

它正在生成堆栈溢出错误。为什么会发生这种情况?

编辑:

我正在尝试创建自己的方法来查找两个列表之间的公共元素。

您从不检查i是否大于input2的长度,在Groovy中,超过List的长度将返回null

因此,在第一个元素上,它将继续围绕循环

if (element == input2[i]) {

对于不断增加的i值,每次调用common函数,因为它从不匹配a

猜测你想做什么,这一切都可以重写为:

def input1 = ['a','b','e','r','t']
def input2 = ['v','n','m','y']
def ans = input1.intersect( input2 )

但是很难确定你想要什么,而且你没有明确地说出来。

编辑

避免堆栈溢出的一种深度递归方法是使用Groovy的蹦床方法。

def common
common = { Object element, Collection list ->
  if( list.size() == 0 ) {                     // element not found.  Return null
    null
  }
  else if( list.head() == element ) {          // element found.  Return it
    element
  }
  else {
    common.trampoline( element, list.tail() )  // Trampoline down the list and check again
  }
}
common = common.trampoline()
def elements = ['a','b','e','v','r','t'].collect { // For each element in this list
                 common( it, ['v','n','m','y'] )   // Find if it's in our other list
               }.findAll()                         // And remove the nulls
assert elements == [ 'v' ]

但在这种情况下,我仍然会使用intersect,上面只是展示Groovy的一种方法,可以避免太深的递归。。。

问题是代码在到达数组input2的末尾时不会停止。如果元素不在input2中,那么它将永远进行递归调用common(元素,++i),这将导致堆栈溢出错误。

最新更新