2つの整数l
とr
を指定してコードチャレンジを行っています。i
とr
(i
およびr
を含む)。関数は、l
とr
の間の奇数を示す整数の配列を返す必要があります。
これが今のところ
static int[] oddNumbers(int l, int r) {
int[] theArray = new int[r];
for (int i = l; i < theArray.length; i++) {
if (i % 2 != 0) {
for (int n = 0; n < theArray.length; n++) {
theArray[n] = i;
}
}
}
return theArray;
}
したがって、現時点では、このコードに値2と5を指定すると、3,5が返されます。ただし、これは33333のみを返します。何が問題なのですか?そして、どうすればこのコードを改善できますか?
私は、範囲内の下限を、まだ奇数ではないにしても、次の奇数に進め、そこから先に進むことによって、これにアプローチします。
static int[] oddNumbers(int l, int r) {
if (r <= l) return null;
l = (l % 2) == 0 ? l + 1 : l;
int size = ((r - l) / 2) + 1;
int[] theArray = new int[size];
for (int i=0; i < size; ++i) {
theArray[i] = l + (i*2);
}
return theArray;
}
ここでの実際の難しさは、奇数の範囲をフラット配列にマッピングするロジックを定式化することです。これを実行すると、配列の生成に必要なのは単純なforループだけであることがわかります。
私たちは2018年です。Java 8!なので、すでにStreams
があります。これで、このようなことを1行で解決できます。そのため、それ:
static int[] oddNumbers(int i, int j){
return IntStream.rangeClosed(i, j).filter(num -> num % 2 == 1).toArray();
}
(あなたが本当にアルゴリズムを学びたいだけでなく、挑戦を解決したくなければ!)
選択のサイズを簡単かつ動的に管理できるストリームまたはリストに作業を委任します。
最後に適切な構造から単純な変換を行うことができるのに、結果の配列のサイズを気にする必要があるのはなぜですか?
static int[] oddNumbers(int l, int r) {
return IntStream.iterate(l, i -> i <= r, i -> ++i)
.filter(i -> i % 2 != 0)
.toArray();
}
static int[] oddNumbers(int l, int r) {
int[] theArray = new int[((r - l) / 2) + 1];
for (int i = l % 2 == 0 ? l : l + 1, j = 0; i <= r; i += 2, j++)
theArray[j] = i;
return theArray;
}