5

Haskellには、アイテムのリストを1つの値に減らすために、アイテムのリストに対して操作を実行できるようにする2つの関数があります。(もちろん、2つ以上ありますが、これらは私が興味を持っている2つです。)それらはfoldl1foldr1です。実行する操作が可換(加算など)の場合、どちらを使用してもかまいません。結果は同じになります。ただし、演​​算が可換でない場合(たとえば、減算)、2つは非常に異なる結果を生成します。例えば:

foldr1 (-) [1..9]
foldl1 (-) [1..9]

最初の答えは5で、2番目の答えは-43です。に相当するJfoldr1は、挿入副詞です/。たとえば、

-/ 1+i.9

これは。と同等ですfoldr1 (-) [1..9]。挿入副詞のように機能するが、右ではなく左に折りたたまれる副詞をJで作成したいと思います。私が思いつくことができる最高のものは次のとおりです。

foldl =: 1 : 'u~/@|.'

したがって、次のように言うことができます。

- foldl 1+i.9

答えとして-43を取得します。これは、左の折り目から予想されるものです。

Jでこれを行うためのより良い方法はありますか?何らかの理由で、y議論を逆にすることは私には効率的ではないようです。おそらく、それに頼る必要なしにこれを行う方法があります。

4

2 に答える 2

3

あなたが説明するよりも左に折りたたむより良い方法はないと思います:

(v~) / (|. list)

これは非常に自然な方法であり、定義のほぼ「文字通りの」実装です。リストを逆にするコストは非常に小さいです(imo)。

左の折り目を実装する他の明白な方法は、設定することです

new_list = (first v second) v rest

例えば:

foldl_once =: 1 :'(u / 0 1 { y), (2}. y)'
foldl =: 1 :'(u foldl_once)^:(<:#y) y'

それで:

- foldl >:i.9
_43

しかし、あなたのやり方は、空間的にも時間的にもこれよりもはるかに優れています。

于 2011-03-09T18:38:10.043 に答える
1
   ($:@}:-{:)^:(1<#) 1+i.9
_43

それがもっと(またはもっと)効率的かどうかはわかりません。

于 2011-03-08T03:57:06.670 に答える