丸三角四角

IT業界にしがみつく新人SEが立派なプログラマになろうともがく奮闘記

【Java】4つの整数和の組み合わせ_Ver1

今回は入力された数値を4つの整数の和で求める際に、いくつの組み合わせができるかを求める問題です。

コード更新しています。解説等はこのままこの記事で解説していますので、解説等読んだ後はVer2のコードを参照してください。

dadainu.hateblo.jp

例として

入力値:35
8 + 9 + 9 + 9 = 35
9 + 8 + 9 + 9 = 35
9 + 9 + 8 + 9 = 35
9 + 9 + 9 + 8 = 35
組み合わせ数:4

上記を実装におこすと以下になります。

import static java.lang.Integer.parseInt;
import static java.lang.System.out;
import java.io.File;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class Sumof4Integers {

    public static void main(String[] args) {
        new Sumof4Integers().sum();
    }

    public void sum() {
        try (Scanner scan = new Scanner(System.in)) {
            sum4Integer(scan);
        } catch (Exception e) {
            System.exit(0);
        }
    }

    public void sum(String inputDataPath) {
        try (Scanner scan = new Scanner(new File(inputDataPath))) {
            sum4Integer(scan);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void sum4Integer(Scanner scan) {
        String inDataStr;
        while ((inDataStr = scan.nextLine()) != null && !"".equals(inDataStr)) {
            int combi = getCombi(getSumTwo(), getSumTwo(), parseInt(inDataStr));
            out.println(combi);
        }
    }

    private int getCombi(int[] abList, int[] cdList, int inData) {
        int combi = 0;
        for (int ab : abList) {
            for (int cd : cdList) {
                combi = (judgeSum(ab, cd, inData)) ? combi + 2 : combi;
            }
        }
        return combi;
    }

    private boolean judgeSum(int ab, int cd, int inData) {
        return (ab == inData - cd) ? true : false;
    }

    private int[] getSumTwo() {
        Set<Integer> sumList = new HashSet<>();
        for (int i = 0; i < 10; i++) {
            for (int j = i; j < 10; j++) {
                sumList.add(i + j);
            }
        }
        return setToArray(sumList);
    }

    private int[] setToArray(Set<Integer> sumList) {
        int abList[] = new int[19];
        int index = 0;
        for (int num : sumList) {
            abList[index++] = num;
        }
        return abList;
    }
}

本当はネストしたループで簡単に実装することができますが、ネストしすぎてちょっと見てくれが良くないなと思ったのでメソッド分割しました。4つの整数を一つずつ出して求めるのも良いですが、2つの整数和のバリエーションを出してから組み合わせを求めるような流れにしました。

テストドライバは以下になっています。

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import volume0.BaseTest;

public class Sumof4IntegersTest extends BaseTest {

    private Sumof4Integers s4i;

    @Before
    public void setUp() throws Exception {
        super.setUp();
        s4i = new Sumof4Integers();
    }

    @After
    public void tearDown() throws Exception {
        super.tearDown();
    }

    @Test
    public void test() {
        try {
            s4i.sum("./data/volume0_0008/in.txt");
            outList = outContent.toString().split("\n");
            assertOut(outList, "./data/volume0_0008/out.txt");
        } catch (Exception e) {
            printErr(e);
        }
    }
}

テストドライバ内で使用した「in.txt」・「out.txt」は以下になります。

in.txt
35
1
out.txt
4
4

今回の問題は以下にあります。

4つの整数の和 | Aizu Online Judge

アルゴリスムで困った時は、以下の本を参考にしてます。Javaに置き換えるのが少々難解ですが、、、

テストドライバで継承しているクラスは以下の記事に記載しています。参考にしてみてください。

dadainu.hateblo.jp