0

私はintの配列を持っています。各要素に 1 を追加する必要があります。特定の定数を各要素に追加する、つまり明示的なループなしで、最短かつ最も一般的な方法は何ですか? オンラインで調べたところ、配列の要素の追加(つまり、連結) に関するページが増え続けています。

各要素をループして定数を追加するよりもエレガントなものはありませんか? ある種の標準ライブラリメソッドはありますか?

さらに言えば、明示的なループなしで 2 つの配列を加算 (つまり、行列の加算) するにはどうすればよいでしょうか?

4

2 に答える 2

1

上記の 2 つのケースをFunctional Javaで記述する方法を次に示します。


1. 各要素に 1 を追加します。

これは関数型プログラミング ライブラリであるため、変更操作は提供しません。ただし、それらは自分で簡単に追加できます。

public static <A> void transform(Array<A> xs, F<A, A> f) {
  for(int i = 0; i < xs.length(); i++) {
    xs.set(i, f.f(xs.get(i)));
  }
}

使用する:

transform(yourArray, Integers.add.f(1));

2. 2 つの行列を追加します。

とを両方の型の 2 つの行列としxssます。次に、それらを追加できます:yssArray<Array<Integer>>

 xss.zip(yss).map(new F<P2<Array<Integer>, Array<Integer>>, Array<Integer>>() {
   public Array<Integer> f(P2<Array<Integer>, Array<Integer>> p) {
     Array<Integer> xs = p._1(); 
     Array<Integer> ys = p._2();
     return xs.zip(ys).map(new F<P2<Integer, Integer>, Integer>() {
       public Integer f(P2<Integer, Integer> q) {
         return q._1() + q._2();
       }
     });  
   }
 });

これは必要以上に冗長に感じるかもしれません。これは、Java がラムダ式をまだサポートしていないためです。それまでの間、 IDE はそのような手法をより親しみやすいものにするのに役立ちます。

于 2012-06-04T05:51:31.327 に答える
0

変更不可能な結果が問題なく、配列の使用に固執していない場合は、かわいいトリックを使用して、可能な限り最後の瞬間まで加算を遅らせることができます。しかし、結果配列全体にアクセスする必要があるとすぐに、パフォーマンス上のメリットが失われ、コードが必要以上に複雑になります。

public class OffsetArrayList extends AbstractList< Integer > {
    private final List< Integer > liUnderlying;
    private final int iOffset;
    public OffsetArrayList( int iOffset, liUnderlying ) {
        this.iOffset = iOffset;
        this.liUnderlying = liUnderlying;
    }
    @Override
    public Integer get( int iIndex ) {
        return liUnderlying.get( iIndex ) + iOffset;
    }
    @Override
    public Integer set( int iIndex, Integer iNewValue ) {
        return liUnderlying.set( iIndex, iNewValue - iOffset ) + iOffset;
    }
    // etc.
}

// create new array
int[] aiInput = new int[] { 23, 98, -45 };
// two object allocations, but no new array created and no additions performed
OffsetArrayList alPlusOne = new OffsetArrayList( 1, Arrays.asList( aiInput ) );
// one addition performed; constant time
assert( alPlusOne.get( 0 ) == 24 );

// benefit murky, as we are adding to the same element repeatedly
for ( int i = 0; i < 1000000; ++i )
    assert( alPlusOne.get( 2 ) == -44 );

// benefit lost, input destroyed
int[] aiOutput = alPlusOne.toArray( aiInput );
于 2012-06-04T05:30:59.773 に答える