題目描述

一個Java介面中,可以包含方法的簽名和欄位,介面可以被用來達成多型的概念。這個題目會讓您練習介面的相關知識。



您有一個AdvancedArithmetic介面,他包含了一個「public abstract int divisorSum(int n)」方法。您必須再寫一個MyCalculator類別去實作這個介面。

divisorSum方法只能輸入一個整數,找出這個整數的所有因數,並將它們加總之後把加總結果回傳。舉例來說,6的因數有1, 2, 3, 6,所以divisorSum方法計算後會回傳12。傳入的整數n的最大值為1000。

原題網址

https://www.hackerrank.com/challenges/java-interface

範例輸入

6

範例輸出

I implemented: AdvancedArithmetic
12

解題概念

如果n為1,直接回傳1;如果n小於1,回傳0。

首先先計算根號n的數,因為n的因數,除了自己本身外,其他的因數必定小於等於根號n。接著從2開始到根號n,逐一尋找可以整除n的數字,並將這些數字加總後,再加上n + 1之後回傳。

參考答案

import java.util.Scanner;

interface AdvancedArithmetic {

    public abstract int divisorSum(int n);
}

class MyCalculator implements AdvancedArithmetic {

    @Override
    public int divisorSum(final int n) {
        if (n == 1) {
            return 1;
        } else if (n < 1) {
            return 0;
        }
        final int sqrtN = (int) Math.floor(Math.sqrt(n));
        // 先找最小質因數
        int sum = 0;
        for (int i = 2; i <= sqrtN; ++i) {
            if (n % i == 0) {
                sum = i;
                break;
            }
        }
        if (sum >= 2) { // 若不是質數,有最小質因數
            // 計算從最小質因數+1到原數除最小質因數的因數
            final int nn = n / sum;
            for (int i = sum + 1; i <= nn; ++i) {
                if (n % i == 0) {
                    sum += i;
                }
            }
        }
        sum += n + 1; //把1和自己本身算進去
        return sum;
    }

}

public class Solution {

    public static void main(final String[] args) {
        final MyCalculator my_calculator = new MyCalculator();
        System.out.print("I implemented: ");
        ImplementedInterfaceNames(my_calculator);
        final Scanner sc = new Scanner(System.in);
        final int n = sc.nextInt();
        System.out.print(my_calculator.divisorSum(n) + "\n");

    }

    static void ImplementedInterfaceNames(final Object o) {

        final Class[] theInterfaces = o.getClass().getInterfaces();
        for (int i = 0; i < theInterfaces.length; ++i) {
            final String interfaceName = theInterfaces[i].getName();
            System.out.println(interfaceName);
        }
    }
}