Java學習記錄22 — 代碼挑戰5

張小雄
18 min readJan 18, 2021

--

題目:All Factors

創立名為printFactors的method,接收名為number的int參數,不用回傳。

若numbere < 1,打印”Invalid Value”

打印出number的所有因數

測試數據:

printFactors(6);
printFactors(32);
printFactors(10);
printFactors(-1);

結果:

1 2 3 6

1 2 4 8 16 32

1 2 5 10

Invalid Value

題目:Perfect Number

創立名為isPerfectNumber的method,接收名為number的int參數,回傳boolean。

number < 1,回傳false。

當number是perfect number回傳true。

perfect number:該數所有因數(不含本身)加起來等於該數。

例、6因數:1、2、3。 1 + 2 + 3 = 6。

6即是perfect number。

測試數據:

System.out.println(isPerfectNumber(6));
System.out.println(isPerfectNumber(28));
System.out.println(isPerfectNumber(5));
System.out.println(isPerfectNumber(-1));

結果:

true

true

false

false

題目:Number To Words

一、創立名為numberToWords的method,接收名為number的int參數。

number < 0,打印”Invalid Value”。

二、創立名為reverse的method,接收int參數,回傳int。

把接收到int參數給反轉並回傳。

例、234 轉成 432,負數也一樣。

使用此方法於numverToWords中,為了打印出正確順序。

三、創立名為getDigitCount的method,接收名為number的int參數,回傳int。

算出number是幾位數並回傳。

若是負數,回傳false。

number < 0,打印”Invalid Value”。

測試數據:

getDigitCount

System.out.println(getDigitCount(0));
System.out.println(getDigitCount(123));
System.out.println(getDigitCount(-12));
System.out.println(getDigitCount(5200));

reverse

System.out.println(reverse(-121));
System.out.println(reverse(1212));
System.out.println(reverse(1234));
System.out.println(reverse(100));

numberToWords

numberToWords(123);
numberToWords(1010);
numberToWords(1000);
numberToWords(-12);

結果:

getDigitCount

1

3

-1

4

reverse

-121

2121

4321

1

numberToWords

One Two Three

One Zero One Zero

One Zero Zero Zero

Invalid Value

題目:Flour Pack Problem

創立名為canPack的method,接收名為bigCount、smallCount、goal的參數,回傳boolean。

bigCount 代表5公斤的麵粉袋

smallCount 代表1公斤的麵粉袋

goal 需要的公斤重

若 bigCount + smallCount >= goal,return true,否則 false

若參數為負數 return false

特別條件注意!

goal分進的袋子至少都要被裝滿,能多不能少。

像是 canPack(1, 0, 4)

這是false 因為bigCount是5公斤袋子 不能裝滿

另外 canPack(0, 5, 4)

有餘多出來倒是可以

canPack(5, 3, 24)

5 * 5 > 24 可是沒裝滿,false

4 * 5 + 23 < 24 ,false

不清楚的話看測試數據來理解

測試數據:

System.out.println(canPack(1, 0, 4));
System.out.println(canPack(1, 0, 5));
System.out.println(canPack(0, 5, 4));
System.out.println(canPack(2, 2, 11));
System.out.println(canPack(-3, 2, 12));
System.out.println(canPack(5, 3, 24));
System.out.println(canPack(4, 18, 19));

結果:

false

true

true

true

false

false

true

題目:Largest Prime

創立名為getLargestPrime的method,接收名為number的參數,回傳int。

若number為負數或者沒有不含任何質數返回-1

找出number裡,因數中的最大質數並返回

測試數據:

System.out.println(getLargestPrime(21));
System.out.println(getLargestPrime(217));
System.out.println(getLargestPrime(0));
System.out.println(getLargestPrime(45));
System.out.println(getLargestPrime(-1));
System.out.println(getLargestPrime(7));
System.out.println(getLargestPrime(45));

結果:

31

-1

5

-1

7

5

題目: Diagonal Star

創立名為printSquareStar的method,接收名為number的int參數,不用回傳。

number < 5 ,打印 “Invalid Value”。

提示:

使用兩層loop

使用 print() 不會換行

使用 println() 可以用來換行

*號以外用空格

圖形提示 要打印*的地方:

第一跟最後的row

第一跟最後的colum

當row = column

當col = number — row — 1

測試數據:

printSquareStar(5);
printSquareStar(8);

結果:

此為5圖形

*****

** **

* * *

** **

*****

此為8圖形

********

** **

* * * *

* ** *

* ** *

* * * *

** **

********

參考答案

All Factors

public static void printFactors(int number) {
if (number < 0) {
System.out.println("Invalid Value");
} else {
for (int i = 1; i <= number; i++) {
if (number % i == 0) {
System.out.print(i + " ");
}
}
}
System.out.println("");
}

打印方面用的是print,效果是不會分行

如果用原本的println,那一個數字就會有好幾行

最下方的println("")是隔開每個數字的空行

沒用這個的話,因為前面用print,最後全部數字都擠在一行

Perfect Number

public static boolean isPerfectNumber(int number) {        int factor_sum = 0;
for (int i = 1; i < number; i++) {
if (number % i == 0) {
factor_sum += i;
}
}
return (factor_sum == number) && (number > 1);
}

Number To Words

public static void numberToWords(int number) {
int reverse_number = reverse(number);
int original_reverse_number = reverse_number;
String word = "";
if (number < 0) System.out.println("Invalid Value");
else if (number == 0) word = "Zero";
while (original_reverse_number > 0) {
int digit = original_reverse_number % 10;
switch (digit) {
case 0:
word += "Zero ";
break;
case 1:
word += "One ";
break;
case 2:
word += "Two ";
break;
case 3:
word += "Three ";
break;
case 4:
word += "Four ";
break;
case 5:
word += "Five ";
break;
case 6:
word += "Six ";
break;
case 7:
word += "Seven ";
break;
case 8:
word += "Eight ";
break;
case 9:
word += "Nine ";
break;
}
original_reverse_number /= 10;
}
if (getDigitCount(number) != getDigitCount(reverse_number)) {
int diff = getDigitCount(number) - getDigitCount(reverse_number);
while (diff > 0) {
word += "Zero ";
diff--;
}
}
System.out.println(word);
}
public static int reverse(int number) {
int value = 0;
while (number != 0) {
value = (value * 10) + (number % 10);
number /= 10;
}
return value;
}
public static int getDigitCount(int number) {
if (number < 0) return -1;
int digit_count = 0;
while (number != 0) {
number /= 10;
digit_count++;
}
return (digit_count != 0) ? digit_count : 1;
}

邏輯是要用到前面兩個method

reverse是因為,沒使用的話,會先輸出個位數

輸入:123

輸出:Three Two One

但我們要的是

One Two Three

所以先reverse倒過來,再從個位數輸出

321

就會是 One Two Three

之後用getDigitCount

是因為像是100有零的這種

因為reverse而會變成1

所以此方法判斷相差幾位數

之後因為reverse的關係

差了幾位就補幾個Zero

輸入:100

reverse變1

1與100比較 差兩位數 補兩個Zero

輸出:One Zero Zero

完成~~

看同學答案後優化

public static void numberToWords(int number) {
int reverse_number = reverse(number);
int original_reverse_number = reverse_number;
String word = "";
if (number < 0) System.out.println("Invalid Value"); for (int i = 0; i < getDigitCount(number); i++) {
int digit = original_reverse_number % 10;
switch (digit) {
case 0:
word += "Zero ";
break;
case 1:
word += "One ";
break;
case 2:
word += "Two ";
break;
case 3:
word += "Three ";
break;
case 4:
word += "Four ";
break;
case 5:
word += "Five ";
break;
case 6:
word += "Six ";
break;
case 7:
word += "Seven ";
break;
case 8:
word += "Eight ";
break;
case 9:
word += "Nine ";
break;
}
original_reverse_number /= 10;
}
System.out.println(word);
}

不用while用for

就不用多寫一段number=0跟

遇到number裡有0時

number與reverse(number)不同的判斷

從0開始啟動,到 < getDigitCount(number) 結束

輸入:

1000

就會走4次的 reverser(1000) % 10

而不會只走1次reverser(1000) % 10

reverse(1000) = 1

走第1次 1 輸出 “One”

第2~4次 因為 0 % 0 = 0

自然就會輸出3次的 “Zero”

One Zero Zero Zero

完成

Flour Pack Problem

public static boolean canPack(int bigCount, int smallCount, int goal) {        if ((bigCount >= 0) && (smallCount >= 0) && (goal >= 0) && ((bigCount * 5) + smallCount >= goal)) {
for (int x = 0; x <= bigCount; x++) {
for (int y = 0; y <= smallCount; y++) {
if ((x * 5) + y == goal) {
return true;
}
}
}
}
return false;
}
}

剛開始沒看清楚題目 還以為很簡單

5分鐘內就能寫完

結果想那些條件邏輯,搞了我1個多小時

一開始一直用%跟各種if來寫

怎麼都寫不出來

有的能滿足 有的不滿足

後來靈光一閃才想到要用for

終於寫出來…

沒特別複雜 看代碼就能理解

話說我發現要用for時 剛開始寫成

if ((bigCount * 5) + smallCount == goal)

一直沒出來我要的結果

還 print x 跟 y

發現數字都對阿 也沒發現錯誤

一直納悶怎麼沒進到 if 給我 true

弄到快生氣 到底尛

後來才發現 自己搞笑了

要寫 (x * 5) + y == goal

同學分享 更簡單

public class FlourPacker {
public static boolean canPack(int bigCount, int smallCount, int goal){
if(bigCount < 0 || smallCount < 0 || goal < 0) { // #1 validation
return false;
}
if(bigCount*5 + smallCount < goal) { // #2 supply must be greater than demand
return false;
}
return (goal%5 <= smallCount);
// #3 regardless of bigCount, remainder of goal has to be less than smallCount
}
}
public class FlourPacker {
public static boolean canPack(int bigCount, int smallCount, int goal){
if(bigCount < 0 || smallCount < 0 || goal < 0) { // #1 validation
return false;
}
if(bigCount*5 + smallCount < goal) { // #2 supply must be greater than demand
return false;
}
return (goal%5 <= smallCount);
// #3 regardless of bigCount, remainder of goal has to be less than smallCount
}
}

上面兩個if 就題目條件

最後一個是用goal / 5(bigCount)的餘數

來與smallCount來做判斷

厲害阿厲害

代碼也簡單了許多

Largest Prime

public static int getLargestPrime(int number) {        if (number <= 1) return -1;        for (int i = (number / 2); i >= 2; i--) {
if (number % i == 0) {
number = i;
}
}
return number;
}

苦戰3小時,實在寫不出來

若能用兩個method倒是很好解

第一個循環跑因數

第二個用做質數確認

只要是因數就確認是否為質數

最後一個就會是最大的質數因數

但題目規定不能多寫method

最後思索不出來 就去看同學答案

實在無語

我寫的超複雜

人家幾行就搞定

這根本是數學題

以後若卡在數學邏輯就不思考那麼久了

耽誤好多學習時間

講解

輸入:21

i 從 21 / 2開始 = 10,依序遞減

目的是從後面開始 找最大的因子

第一個符合的是7

number = 7

新的number為7

下一輪 i 從 6到2 都沒有7的因數

結束循環

最終返回新number7

Diagonal Star

public static void printSquareStar(int number) {        if (number < 5) System.out.println("Invalid Value");
else {
for (int row = 1; row <= number; row++) {
for (int col = 1; col <= number; col++) {
if ((row == 1) || (col == 1) || (row == number) || (col == number) || (row == col) || (col == number - row + 1)) {
System.out.print("*");
} else {
System.out.print(" ");
}
if (col == number) System.out.println();
}
}
}
}

原本題目的最後一個提示 看半天真不知道在寫啥

最後一個規則弄不出來 卡了一小時之後

記取上題教訓 直接去看答案

原來要用到number

我根本沒想到 難怪弄不出來

圖形提示最後一個規則 那是 i 從0開始

但我為了方便紙筆計算 自己是從1開始

所以寫出來的跟提示不同

這題我給自己最低要求是

完成最外圍框框的打印

圖形的邏輯我不會講

看同學分享此題邏輯

public class DiagonalStar{
public static void printSquareStar(int number){
if(number < 5) System.out.println("Invalid Value");
else{
for (int row = 0; row <number; row++){
for (int column=0; column<number; column++){
if(row==0 || row==number-1) System.out.print("1"); // top and bottom rows
else if(column==0) System.out.print("2"); // left column
else if(column==number-1) System.out.print("3"); // right column
else if(column==row) System.out.print("4"); // diagonal down to right
else if(column==number-1-row) System.out.print("5"); // diagonal down to left
// alternative to lines 7-11 // if(row==0 || row==number-1 || column==0 || column==number-1 || column==row || column==number-1-row) System.out.print("*");
else System.out.print(" "); // empty space between numbers
}
System.out.println(""); // puts a return to the row
}
}
}
}

輸出結果

11111111
24 53
2 4 5 3
2 45 3
2 54 3
2 5 4 3
25 43
11111111

1、2、3、4的規則都還蠻簡單

5的規則就是4的相反

右上到左下

順代一提

for (int row = 1; row <= number; row++) {
for (int column = 1; column <= number; column++) {
if (column == number + 1 - row) System.out.print("5");
else if (column == 1) System.out.print("2");
else if (column == number) System.out.print("3");
else if (column == row) System.out.print("4");
else if (row == 1 || row == number) System.out.print("1");
else System.out.print(" ");
}
System.out.println("");
}

多個if滿足條件時,最上面的if先執行

我把1跟5的位置互換了

21115
24 53
2 5 3
25 43
51113

最左上跟最右上不是原本的1

因為2跟5先滿足了,而沒有打印出1

這樣應該就滿清楚了

若還不清楚可以開debug一步一步的看

Intellij — Debug 的使用方法

--

--

張小雄
張小雄

Written by 張小雄

記錄成為軟體工程師的過程

No responses yet