• ベストアンサー

配列

最後にもう一つだけお願いします。ずっと格闘しても解決できません・・ 配列の中の数字で、偶数を全て奇数の前にもって行きます 例) {1,0,1,0,0,1,1} → {0,0,0,1,1,1,1} {3,3,2} → {2,3,3} {2,2,2} → {2,2,2} 流れとしては、まず奇数の数を数えます。これは何回シフトするから知るためです。 配列0から奇数を探し、あればそれを一番最後の配列へとシフトします。 奇数を探す作業が一度終わっても、まだシフトさせないといけない奇数があるかもしれないので(奇数が連続で並んでる場合)、最初に数えた奇数の数分だけちゃんとシフトするようにしようと思います。 public void evensLeft(int[] array) { int odd=0; for (int i = 0; i < array.length; i++) { if(array[i]%2!=0) odd++; //奇数の個数 } while (odd>0) { //奇数分シフトするためのカウント for(int j=0;j<array.length;j++){ //奇数を探す if (array[j] % 2 != 0) { odd--; //奇数のカウントを1減らす for (int k = j; k < array.length-1; k++) { //その奇数を一番最後に移動 int temp = array[k+1]; array[k+1] = array[k]; array[k] = temp; } } } } return array; } いくつかの例では動くのですが、{3,3,2}の例だと配列0に3が来てしまいます。色々変えてみても結果無理でした・・・ どなたかご教授お願いします。

  • Java
  • 回答数5
  • ありがとう数4

質問者が選んだベストアンサー

  • ベストアンサー
  • isi0611
  • ベストアンサー率34% (46/134)
回答No.5

お疲れ様です。 No.4さんのおっしゃるように、まず偶数、奇数に分けた方が やりやすいかと思います。 ArrayListというクラスでaddAllというメソッドがあり、リストの末尾に、指定されたすべての要素を追加できます。 なので、まず1つ目のArrayListに偶数を、次に2つ目のArrayListに奇数を、そして偶数リストにaddAllで奇数リストをつけてやればきれいにできるかと思いますよ。 参考までに public void evensLeft(int[] array) { ArrayList<Integer> gusu = new ArrayList<Integer>(); ArrayList<Integer> kisu = new ArrayList<Integer>(); for (int i = 0; i < array.length; i++) { if (array[i] %2 == 0) { gusu.add(new Integer(array[i])); } else { kisu.add(new Integer(array[i])); } } gusu.addAll(kisu); for (int i = 0; i < gusu.size(); i++) { array[i] = (gusu.get(i)).intValue(); } }

lockwell
質問者

お礼

先ほどNo.4さんのおっしゃっていたArrayListを調べていたのですが、isi0611さんの例でArrayListのやり方がわかりました! 非常に参考になりました!ありがとうございます! 今JAVAの問題を解く練習をしているので、またわからないところがあったら質問させてください。 皆さん本当にありがとうございました!

その他の回答 (4)

  • yuji
  • ベストアンサー率37% (64/169)
回答No.4

マージソートみたいに、2つの配列に分けて、それを最後に1つにまとめてみては? ただし、配列だと今回みたいに個数が不定の場合に操作しずらいので Listを使うのがいいかと思います。 1)奇数用のArrayList, 偶数用のArrayListを用意する。 2)forループを使い、元の配列を走査して、  奇数だったら奇数用のArrayListに追加、偶数だったら偶数用のArrayListに追加。 3)結果用の配列を用意する。 4)forループを使い、偶数用のArrayList,奇数用のArrayListの順に  結果用の配列に入れていく。

lockwell
質問者

お礼

あぁなるほど。確かにあらかじめ分けたいものをわけといたほうがいいですね。ありがとうござます!

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.3

while (odd>0) { //奇数分シフトするためのカウント   for(int j=0; odd > 0; j++){ //奇数を探す     if (array[j] % 2 != 0) {       odd--; //奇数のカウントを1減らす       //その奇数を一番最後に移動       int tmp = array[j];       for (int k = j+1; k < array.length; k++) {        array[k-1] = array[k];       }       array[ array.length - 1] = tmp;       // 入れ替えをしたのでもう一度検査       j--;     }   } }

  • askaaska
  • ベストアンサー率35% (1455/4149)
回答No.2

あなたはよっぽど 配列の要素の隣同士の入れ替えが好きなのね。 同じサイズの新しい配列を用意して そこにはめ込んでいく方が楽でしょうに。 {3,3,2}だとわかりにくいから{3,5,2}で表現するけど あなたのように隣同志を入れ替えると {5,2,3}になっちゃうのよね。 最初に3と5を入れ替えて 次に参照するインデックスが1だから 先頭に来てしまった5がもう相手されなくなってしまうわけ。 新しい配列を用意してあげれば 元の配列を頭から参照して行って 偶数なら頭から、奇数なら途中(偶数の数)から埋めていけばいいだけ。 なぜか知らないけど あなたはいろいろ難しく考えすぎている。 (ずどどーん:荒木飛呂彦的効果音)

lockwell
質問者

お礼

そうなのです。ずっと頭で隣同士でやると思い込んでいました・・・ そのせいで奇数が連続しいるケースで困っていたのです・・・。 これからは必要な時は新しく配列を定義してやっていこうと思います。ありがとうございました!

  • koko_u_u
  • ベストアンサー率18% (216/1139)
回答No.1

>配列の中の数字で、偶数を全て奇数の前にもって行きます 単純に「偶数」<「奇数」とするような「比較演算子」を定義して Arrays.sort() に渡せばいいような気がしますけど

関連するQ&A

  • ソート

    お世話になります。配列のソートなのですが、どうも思い通りの結果になりません。 配列の中から最大値と最小値を探し、最小値を配列0に、最大値を配列の最後に移動します。その2つ以外の数字の順番は変えません。 例) {4,3,2,0,1,2} 最小値は0、最大値は4なので→{0,3,2,1,2,4} {4,3,2,1} → {1,3,2,4} {1,3,2,4,} → {1,3,2,4} 流れとしては、まず最小値を求め配列0に移動させ、次に最大値を求め配列の最後に移動させようと思います。 プログラムは以下のように組みました。 public int[] sortOfSort(int[] array) { int count_min = 0; int min = array[0]; for (int i = 0; i < array.length-1; i++) { // 最小値を求める if (min > array[i + 1]) { min = array[i + 1]; count_min++; // 最小値の配列のインデックスを確保 } } for (int k = count_min; k > 0; k--) { // 最小値の移動 int temp_min = array[k - 1]; array[k - 1] = array[k]; array[k] = temp_min; } int count_max = 0; int max = array[0]; for (int j = 0; j < array.length-1; j++) { // 最大値を求める if (max < array[j + 1]) { max = array[j + 1]; count_max++; // 最大値の配列のインデックスを確保 } } for (int l = count_max; l < array.length-1; l++) { //最大値の移動 int temp_max = array[l + 1]; array[l + 1] = array[l]; array[l] = temp_max; } return array; } 間違っているところがわかりましたら宜しくお願いします。

    • ベストアンサー
    • Java
  • 配列の中に複数存在する数がいくつあるか

    お世話になります。配列の中に同じ数が存在する数がいくつあるかを調べたいのですが、途中でつまづいてしまいました。 例えば配列arrayの中に、0, 0, 5, 0, 5, 1, 5といった数が格納されているとしたら 複数ある数は0と5の2つなので、2を返す、というだけのプログラムです。 int n=array.length; int cnt=0; for(int i=0;i<n;i++){ for(int j=i+1;j<n;j++){ if(array[i]==array[j]){ cnt++; break; } } } return cnt; forループで配列0から同じ数を順番に調べ、もしヒットすればカウントを増やして内側のループをブレイクし、配列1からまた順番に調べようとしたのですが、 上の例の場合、配列0と配列1が同じ数(0)ですので、カウントが余計に増えてしまいます。 どのように組めばうまく動作するでしょうか。宜しくお願いします。

    • ベストアンサー
    • Java
  • 配列について

    以下の配列についての問題でわからないことがあるので、教えてください。 /* x と y の積を求める。 */ #include <stdio.h> int main(void) { int x[2][3] = {{1,2,3}, {4, 5, 6}}; int y[3][2] = {{1, 5}, {5, 3}, {8, 1}}; int ans[2][2] = {0}; int i, j, k, temp; for(i = 0; i < 2; i++) { for (k = 0; k < 2; k++) { temp = 0; for(j = 0; j < 3; j++) { temp += x[i][j] * y[j][k]; } ans[i][k] = temp; } } for(i = 0; i < 2; i++) { for(j = 0; j < 2; j++) { printf("%4d",ans[i][j]); } putchar('\n'); } return(0); } 以下の部分について詳しく説明してもらえないでしょうか? int ans[2][2] = {0};  int i, j, k, temp; for(i = 0; i < 2; i++) { for (k = 0; k < 2; k++) { temp = 0; for(j = 0; j < 3; j++) { temp += x[i][j] * y[j][k]; } ans[i][k] = temp; } }

  • 多次元配列とfor文について

    javascriptの配列について質問です。 例えば: var arrXXX = new Array(); function samplefunc{ //3次元配列の種類の作成 for (m = 0; m < aaa.length ; m++) { //連想配列作成 arrXXX .push(aaa[m]); } for (j = 0; j < bbb.length; j++) { for (i = 0; i < ccc.length; i++) { arrXXX[aaa[j]] = new Array(ccc.length); arrXXX[aaa[j]][i] = new Array(ccc.length); for (k = 0; k < ddd.length; k++) { arrXXX[aaa[j]][i][k] = eee;     ここでは配列を適切に使える・・・ } } } ここでarrXXXを使いたいが、3次元配列でなくなっている?!  arrXXX[~][0][0]はnullまたはオブジェクトではありません・・・がでます。 } 結局、for文を完全にでてしまうと、せっかくつくった配列がダメになってしまいます。どうすればfor文外で配列を使用できるのか教えてください!

  • 配列のソートと削除

    String型のstrToRemoveで与えられた文字列を配列から探し、あればそれ以降の配列の数字をすべて左にシフトします。 なので配列の大きさは1小さくなります。その結果の配列をreturnで返します。 例) ({"A","B","C","D","B"}, "B")配列1にBがあるのでそれ以降の文字列をすべて左にシフト→ {"A","C","D","B"} ({"A","B","C","D","B"}, "A") 配列0にAがあるのでそれ以降の文字列を左にシフト→ {"B","C","D","B"} プログラムは以下のように組みました。 public class ArrayFun { public String[] oneRemoved(String[] array, String strToRemove) { int count = 0; for (int i = 0; i < array.length; i++) {      if (strToRemove.equals(array[i]) && count == 0) {        for (int j = i; j < array.length - 1; j++) {          array[j] = array[j + 1];        }          count++;      } }      array = new String[array.length - 1];      array[array.length - 1] = null;      return array; } } ちなみにcountは、一度シフトすればもう同じ文字列がそれ以降の配列にあってもシフトはしないので、countでシフトしたかどうかを判断しようと思い付けました。 これでテストメソッドも作るのですが、 import static org.junit.Assert.*; import org.junit.Test; public class ArrayFunTest { @Test public void testoneRemoved() { ArrayFun af = new ArrayFun(); String[] a1 = {"A","B","C","D","B" };//元の配列 String[] a2 = {"A","BB","CCC","DDD","B"};//元の配列 String[] a3 = {"B","C","D","B"};//シフト後の配列 String[] a4 = {"A","BB","CCC","DDD","B"};//シフト後の配列 assertEquals(a3, af.oneRemoved(a1, "A")); assertEquals(a4, af.oneRemoved(a2, "NotHere")); } } 以上のように組むと、assertEqualsの真ん中に黒線が入って自動的に@SuppressWarnings("deprecation")が加えられてしまいます。 実行結果は、({"A","B","C","D","B"}, "A") の例だと、配列0にB が入るはずがnullになっている、とエラーがでます。 どのようにしたら正常に動かせるでしょうか?宜しくお願いします。

    • ベストアンサー
    • Java
  • 配列について

      class Array01{ public static void main(String[] args){ int[][] ia = {{11,12},{21},{41,42,44}}; for(int i = 0; i < ia.length; i++){ for(int j = 0; j < ia[i].length; j++ ){ System.out.print(ia[i][j] + " "); } System.out.println(); } } } } (i < ia.length) と (j < ia[i].length)のとこの意味が分かりません。特にiaとia[i]の違いなんか教えてもらえると助かります。for文については理解してるんですが・・・

    • ベストアンサー
    • Java
  • Javaの二次元配列についてです

    配列要素を 1, 2, 3, 4, 5 2, 2, 3, 4, 5 3, 3, 3, 4, 5 4, 4, 4, 4, 5 5, 5, 5, 5, 5 のようにしたいのですがどうすればよろしいでしょうか? int[][] a = new int[5][5]; for (int i = 0; i < a.length; i++) { for (int j = 0; j < a[i].length; j++) { ~ここの処理を教えてください~ } }

    • ベストアンサー
    • Java
  • テストメソッド

    テストメソッドを使いプログラムを実行させたいのですが、テストメソッドにエラーが出て正常にプログラムが動くかどうか調べられません。 問題は、配列0の数字を、int型のnumShiftsで与えられた数字の回数だけ一番後ろへ移動させ、それ以外の配列の数字を左へシフトさせます。 つまり、一度配列0の中身を一番後ろに持っていくと、配列1の数字が配列0にくるので、それをまた一番後ろにもって行きます。 そしたら配列2の数字が配列0に来ます。それをまた一番後ろにもって行きます。それをnumShifts回繰り返します。 例) ({1,2,3,4,5,6,7}, 3) 3回移動→ {4,5,6,7,1,2,3} ({1,2,3,4,5,6,7}, 0) 0回移動→ {1,2,3,4,5,6,7} ({1,2,3}, 5) 5回移動→ {3,1,2} プログラムは以下のように組みました。 public class ArrayFun { public void shiftNTimes(int[] array, int numShifts) { for (int i = 0; i < numShifts; i++) { //numShifts回繰り返す for (int j = 0; j < array.length-1; j++) { //配列をシフト int temp = array[j+1]; array[j+1] = array[j]; array[j] = temp; } } } } テストメソッドは以下です。 import static org.junit.Assert.*; import org.junit.Test; public class ArrayFunTest { @Test public void testshiftNTimes() { ArrayFun af = new ArrayFun(); int[] a1 = { 1, 2, 3, 4, 5, 6, 7 };//元の配列 int[] a2 = { 1, 2, 3, 4, 5, 6, 7 };//元の配列 int[] a3 = { 1, 2, 3 };//元の配列 int[] a4 = { 4, 5, 6, 7, 1, 2, 3 };//シフト後の配列 int[] a5 = { 1, 2, 3, 4, 5, 6, 7 };//シフト後の配列 int[] a6 = { 3, 1, 2 };//シフト後の配列 assertEquals(a4, af.shiftNTimes(a1, 3)); assertEquals(a5, af.shiftNTimes(a2, 0)); assertEquals(a6, af.shiftNTimes(a3, 5)); } } エラーは、assertEqualsに赤線が出てしまうことです。 このタイプのAssertでのassertEquals(Object, Object)は、(int[], void)に適切ではないと表示されます。 他のテストメソッドではこのようなエラーは出ないのですが・・・。どなたか解決方法をご存知であれば宜しくお願いします。

    • ベストアンサー
    • Java
  • 配列長参照のオーバーヘッド

    for等ループでループ終了条件に配列長を使用する場合、配列長を毎回参照する場合と一旦変数に格納して参照する場合、定数を使用する場合と処理速度の差はありますか? つまり 1、for( int i = 0; i < array.length; i++ ) { ... } 2、for( int i = 0; i < len; i++ ) { ... } *(int len=array.length) 3、for( int i = 0; i < 10; i++ ) { ... } *(int[] array = new int[10]) forループ内の処理のメモリ使用量の多寡は不明で、毎ループで読み取られる全ての変数はコンピュータのキャッシュに残るかどうかは不明だとします。

    • ベストアンサー
    • Java
  • javascriptの2次元配列をソートの仕方

    function word_grouping(data) { var code = data; //先頭についている”code="を除去 code = code.replace("code=",""); var = code.split(","); var alpha =new Array(); alpha = ['A','B','C','D','E','F','G','H','I','J','K','L','M']; //2次元配列作成 var array = new Array(); for (i =0; i < alpha.length; i++) { array[i] = [' ','0']: } //グループ名を格納 for( i = 0; i <alpha.length; i++){ array[i][0] = alpha[i] //0番目の項目から順番にグループごとに分ける for( i = 0; i < sp.length; i++){ group = sp[i].substring(0.1); //どのグループに所属しているか調べる for( j = 0; j < alpha.length; j++){ //一致したグループの配列にカウント+1していく if(group == array[j][0]{ array[j][1]++; } } } メモ ・spにはグループのどこかに所属する20個のキーワードが入っていてそれをグループに振り分けている ・グループ分けには”A001”のAだけみて振り分けています したいこと ・arrayに入ったキーワードの数を降順で並び替えたい 分からない所 ・2次元配列をsortする仕方 こんな感じなんです わかる方回答お願いします。

専門家に質問してみよう