配列のソートと削除

このQ&Aのポイント
  • 配列の要素を左にシフトして、指定された文字列を削除するプログラムの作成方法について教えてください。
  • テストメソッドを実行する際にエラーが発生し、配列の要素が正しくシフトされない問題が発生しました。正常に動作させるための対処方法を教えてください。
  • 質問の要点は、指定された文字列を配列から削除し、要素を左にシフトするプログラムが正しく動作しないことです。対応するテストメソッドを作成して、エラーが発生する理由を解明し、問題を修正してください。
回答を見る
  • ベストアンサー

配列のソートと削除

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
  • 回答数1
  • ありがとう数1

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

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

どうしてってあなた array = new String[array.length - 1]; しているじゃない。 それぞれの処理の意味を理解しないとダメよ。 あなたのソースを活かして変更を加えるのなら oneRemovedメソッドの開始直後に サイズarray.length - 1の配列を新たに宣言。 forループでこの配列に格納する、 と言うことをすればOK。 拡張性を考慮するなら サイズarray.length - 1の配列を新たに宣言せずに ArrayListのインスタンスを作成し、 for文でaddしていくといいよ。

lockwell
質問者

お礼

ありがとうございます!メソッド直後に新しい配列を宣言して代入していく方法でできました! 上記のテストメソッドで正常にうごきました!ありがとうございます! 他の問いでもひっかかっているので、また別に質問させていただきます

関連するQ&A

  • 多次元配列のソートがうまくいかない

    多次元配列のソートがうまくいかない 質問失礼します. 以下のような,String型,int型,double型の混在した多次元配列([3][3]の配列)をソートするプログラムを作成しました. このプログラムでは3番目の項目でソートを行っています. 問題点なのですが, 3番目の項目がdouble型の一桁(例えばarray[1][2]が2.0)ならばうまくソートできるのですが, 一つを2桁(例えばarray[1][2]を10.0)にすると何故か先頭の数(10.0の場合1)を基準にソートされてしまっているようです・・・ 配列へのデータの入れ方が間違っているのでしょうか? 原因がはっきりわからず困っているのですが, わかる方いましたらよろしくお願いします. public class Sort_test { /** * @param args */ public static void main(String[] args) { // TODO 自動生成されたメソッド・スタブ String[][] array = new String[3][3]; array[ 0 ][ 0 ] = "A"; array[ 0 ][ 1 ] = 2001+""; array[ 0 ][ 2 ] = 9.0+""; array[ 1 ][ 0 ] = "B"; array[ 1 ][ 1 ] = 1001+""; array[ 1 ][ 2 ] = 2.0+""; array[ 2 ][ 0 ] = "C"; array[ 2 ][ 1 ] = 3001+""; array[ 2 ][ 2 ] = 6.0+""; TheComparator comparator = new TheComparator(); // 3番目の項目でソートするように設定 comparator.setIndex( 2 ); // ソート実施 Arrays.sort( array, comparator ); dump(array); } public static void dump( String[][] array ) { for ( int i = 0;i < array.length;i++ ) { for ( int j = 0; j < array[ i ].length;j++ ) { System.out.print( "\t" + array[ i ][ j ] ); } System.out.println(); } } } //多次元配列ソート用クラス class TheComparator implements Comparator { /** ソート対象のカラムの位置 */ private int index = 0; /** ソートするためのカラム位置をセット */ public void setIndex( int index ) { this.index = index; } public int compare( Object a, Object b ) { String[] strA = ( String[] ) a; String[] strB = ( String[] ) b; return ( strA[ index ].compareTo( strB[ index ] ) ); } }

    • ベストアンサー
    • 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する仕方 こんな感じなんです わかる方回答お願いします。

  • ソート

    お世話になります。配列のソートなのですが、どうも思い通りの結果になりません。 配列の中から最大値と最小値を探し、最小値を配列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_aに、100件の文字列要素が格納されています。 別の配列array_bには、80件の文字列要素が格納されています。 array_aの要素、array_bの要素共に重複するものはありません。 array_b中に存在する要素はすべてarray_a中にも存在します。 array_aにあり、array_bにはない要素で構成されたarray_cの作り方を教えてください。 例えば $array_a=array("a","b","c","d","e","f","g"); $array_b=array("e","b","d"); なら、 $array_c=array("a","c","f","g") になります。 配列array_aとarray_bは、 $array_b=array("b","b","d"); であったり、 $array_a=array("a","a","b","c","d","e","f","g"); といった「重複する要素を含むパターン」はありません。要素はすべてユニークです。 よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • 配列

    最後にもう一つだけお願いします。ずっと格闘しても解決できません・・ 配列の中の数字で、偶数を全て奇数の前にもって行きます 例) {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
  • 多次元配列のカウント+1の仕方

    多次元配列のカウント+1の仕方 下記のような多次元配列(ちなみに、これって二次元配列ですか?)があるとき、 常に、「2列目の0がある数+1」を返すようにしたいのですが、 どうすればよいのでしょうか? $data[0][1]とか$data[1][1]とか$data[2][1]とかの意味です。 下記の例でいくと、2列目に0が3つあるので、数値の4を返したいのですが…、 ■$data 1,0,A1,B1,C1 2,0,A2,B2,C2 3,0,A3,B3,C3 4,2,A4,B4,C4 ■var_dump($data); array(4) { [0]=> array(5) { [0]=> string(1) "1" [1]=> string(1) "0" [2]=> string(2) "A1" [3]=> string(2) "B1" [4]=> string(2) "C1" } [1]=> array(5) { [0]=> string(1) "2" [1]=> string(1) "0" [2]=> string(2) "A2" [3]=> string(2) "B2" [4]=> string(2) "C2" } [2]=> array(5) { [0]=> string(1) "3" [1]=> string(1) "0" [2]=> string(2) "A3" [3]=> string(2) "B3" [4]=> string(2) "C3" } [3]=> array(5) { [0]=> string(1) "4" [1]=> string(1) "2" [2]=> string(2) "A4" [3]=> string(2) "B4" [4]=> string(2) "C4" } }

    • ベストアンサー
    • PHP
  • 配列

    String型の配列の中の文字列の文字数を数える方法で困っています。 問題は、int型の変数lenで与えられた数字よりも大きい文字数の文字列はいくつあるか調べます。 例) stringsLongerThan({"a","ab","abc"}, 0) 3つ全ての文字列の文字数は0より大きいので3を返す stringsLongerThan({"a","ab","abc"}, 2) "abc"の文字数が2より大きいので1を返す stringsLongerThan({"a","ab","abc","abcd","abcde","abcdef","abcdefg"}, 3) "abcd","abcde","abcdef","abcdefg"の4つが文字数3より大きいので4を返す 途中まで組んだのですが、配列array[]の中の文字列の文字数を数えるにはどうしたらよいのでしょうか? public int stringsLongerthan(String[] array, int len){       int result=0;      for(int i=0;i<array.length;i++){        //ここで配列array[i]の文字列の文字数を数える       int count=文字数;       if(cont>len)        result++;     }      return result; } 宜しくお願いします。

    • ベストアンサー
    • Java
  • 配列をソートさせたとき、もう一方の配列も同じようにソートさせたい

    タイトルが意味不明で申し訳ありません。 二つの配列があるとします。 片方には文字列、もう片方には数値が記録されているもので、最大添え字は同じです。 この数値の大きい順に並べ替えを行いたいのですが、 name[0]とcount[0] name[1]とcount[1] ・ ・ をペアで並べ替えたいのですが、その方法が分かりません。 sort関数を使うとどうしても片方のみしかソートできないし、バブルソートを用いて試みましたが、どうも並び替えられません。 連想配列を使う考えもありましたが、2つの配列をどうやって一つのハッシュに格納すればいいか分からず断念しました。 バブルソートの方にバグがあるのかもしれませんが、何か方法があればご教授いただけると幸いです。 よろしくお願いします。 バブルソート部分のソース(配列は@filelistと@countを使用) # ソート処理 for($i=0;$i<$#filelist;$i++){ for($j=0;$i<$j;$j++){ if($count[$i]<$count[$i+1]){ $tmp=$count[$i]; $count[$i]=$count[$i+1]; $count[$i+1]=$tmp; $tmp=$filelist[$i]; $filelist[$i]=$filelist[$i+1]; $filelist[$i+1]=$tmp; $k=$j; } $i=$k; } }

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

    テストメソッドを使いプログラムを実行させたいのですが、テストメソッドにエラーが出て正常にプログラムが動くかどうか調べられません。 問題は、配列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
  • C言語 ソートについて

    #include <stdio.h> #include <stdbool.h> #define NUM_ARRAY 4 #define NUM_DATA 5 int count_swap = 0; // 交換回数 int count_comparison = 0; // 比較回数 void selection_sort(int a[], int n) { } int main(void) { int data[NUM_ARRAY][NUM_DATA] = {{9, 7, 5, 6, 8}, {9, 8, 7, 6, 5}, {5, 6, 7, 8, 9}, {5, 6, 8, 7, 9}}; for (int i = 0; i < NUM_ARRAY; i++) { count_swap = 0; count_comparison = 0; int d[NUM_DATA]; copy_array(data[i], d, NUM_DATA); // 配列のコピー printf("----------------\n"); print_array(d, NUM_DATA); // ソート前の配列の表示 selection_sort(d, NUM_DATA); // 挿入ソートの実行 print_array(d, NUM_DATA); // ソート後の配列の表示 printf("比較回数: %d\n", count_comparison); // 比較回数の表示 printf("交換回数: %d\n", count_swap); // 交換回数の表示 } } 上の雛形を使って選択ソートを実行するという問題なのですが途中までそれっぽいのは出来たのですが上手くいかないので解答をお願いします。 下に自分が今書いているものを置いておきます。 #include <stdbool.h> #include <stdio.h> #define NUM_ARRAY 4 #define NUM_DATA 5 int count_swap = 0; int count_comparison = 0; void swap(int d[], int i, int j) { count_swap += 1; printf("swap a[%d] = %d, a[%d] = %d\n", i, d[i], j, d[j]); int temp = d[i]; d[i] = d[j]; d[j] = temp; } void copy_array(int *a, int *b, int n) { for (int i = 0; i < n; i++) { b[i] = a[i]; } } void print_array(int d[], int n) { for (int i = 0; i < n; i++) { printf("%d ", d[i]); } printf("\n"); } bool compare(int d[], int i, int j) { count_comparison += 1; printf("compare a[%d] = %d, a[%d] = %d\n", i, d[i], j, d[j]); if (d[i] > d[j]) { return true; } else { return false; } } void selection_sort(int d[], int n) { int min; for (int i = 0; i < n - 1; i++) { min = i; for (int j = i + 1; j < i; j++) { if (compare(d, min, j)) { min = j; } } swap(d, i, min); print_array(d, n); } } int main(void) { int data[NUM_ARRAY][NUM_DATA] = { {9, 7, 5, 6, 8}, {9, 8, 7, 6, 5}, {5, 6, 7, 8, 9}, {5, 6, 8, 7, 9}}; for (int i = 0; i < NUM_ARRAY; i++) { count_swap = 0; count_comparison = 0; int d[NUM_DATA]; copy_array(data[i], d, NUM_DATA); // 配列のコピー printf("----------------\n"); print_array(d, NUM_DATA); // ソート前の配列の表⽰ selection_sort(d, NUM_DATA); // 挿⼊ソートの実⾏ print_array(d, NUM_DATA); // ソート後の配列の表⽰ printf("⽐較回数: %d\n", count_comparison); // ⽐較回数の表⽰ printf("交換回数: %d\n", count_swap); // 交換回数の表⽰ } }

専門家に質問してみよう