2

私はこのコードを持っています:

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)
}

スタックオーバーフローエラーが発生しています。なぜこうなった?

編集:

2つのリスト間で共通の要素を見つける独自の方法を作成しようとしています。

4

2 に答える 2

2

iがの長さよりも大きいかどうかを確認することはありませんinput2。Groovyでは、Listリターンの長さを超えています。null

したがって、最初の要素では、ループし続けます

if (element == input2[i]) {

の値が増え続ける場合は、関数が一致することはないため、毎回関数iを呼び出しますcommona

あなたがやろうとしていることを推測すると、これはすべて次のように書き直すことができます。

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

しかし、あなたが何を望んでいるのかを確認するのは難しいです、そしてあなたは明示的に言わないでください。

編集

One method of deep recursion that avoids Stack Overflows is to use Groovy's trampoline method.

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' ]

But I'd still use intersect in this case, the above is just to show one of Groovy's ways you can avoid too-deep recursion...

于 2012-07-26T11:36:43.170 に答える
0

The problem is that your code doesn't stop when reaches the end of array input2. If element is not in input2 then it will keep making recursive calls common(element,++i) forever which results in stack overflow error.

于 2012-07-26T11:38:09.847 に答える