ぐぬぬ…マージの実装って難しい。
番兵法でしようとしたら、配列の操作にてこずってしまったので安直な方法での実装で終了しました。
(一応、番兵法でも作ったものの、配列のままではやりづらいのでVectorに入れ直して操作してました)
ソースコードは以下の2つ。
public class Merge { private Integer[] mergedArray; public Merge(Integer[] a, Integer[] b){ mergedArray = new Integer[a.length + b.length]; for(int i = 0, j = 0, p = 0; i < a.length || j < b.length; p++){ if(i < a.length && j < b.length){ if(a[i]<=b[j]) mergedArray[p] = a[i++]; else mergedArray[p] = b[j++]; } else{ if(i < a.length) mergedArray[p] = a[i++]; else mergedArray[p] = b[j++]; } } } public Integer[] getMergedArray(){ return mergedArray; } }
Merge.java
import org.junit.*; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; public class MergeTest { private Merge initMerge(Integer[] a, Integer[] b){ return new Merge(a, b); } @Test public void getMergedArrayTest(){ assertThat((initMerge(new Integer[]{1,2,5,6,7}, new Integer[]{3,4,8}).getMergedArray()), is(new Integer[]{1,2,3,4,5,6,7,8})); assertThat((initMerge(new Integer[]{100,300,400,600}, new Integer[]{200,500}).getMergedArray()), is(new Integer[]{100,200,300,400,500,600})); } }
MergeTest.java
for文を使ったら、妙なfor文になってしまった気が…。
while文でもよかったかな、とは思ったり。
assertThat()の文が長くなりすぎてますね・・・。改行もどの辺ですると見やすいのやら・・・。
テストコードのリファクタリング。
public class MergeTest { private Merge initMerge(Integer[] a, Integer[] b){ return new Merge(a, b); } private void testMergedArray(Integer[] actualA, Integer[] actualB, Integer[] expected){ assertThat((initMerge(actualA, actualB).getMergedArray()), is(expected)); } @Test public void getMergedListTest(){ testMergedArray(new Integer[]{1,2,5,6,7}, new Integer[]{3,4,8}, new Integer[]{1,2,3,4,5,6,7,8}); testMergedArray(new Integer[]{100,300,400,600}, new Integer[]{200,500}, new Integer[]{100,200,300,400,500,600}); } }
assertThat()の重複除去をしました。マージをしているコードも本当はメソッドの抽出を行って、if-else文の部分も書きなおすべきだと思われます。