# Java第四章
#### &&、||、if-else、for、while、List
---
## 1. &&、||
:::success
|運算|1|2|
| -------- | -------- | -------- |
| and | & | && |
| or | \| | \|\||
& 計算完兩邊後,若兩邊皆為 True 則返回True
&& 從第一個算式開始計算,每次計算都判斷是否為True,如有False,則直接返回False(理論上效率較高)
\| 計算完兩邊後,若兩邊有至少一個 True 則返回True
\|\| 從第一個算式開始計算,每次計算都判斷是否為True,如有True,則直接返回True,若算豆最後都沒有,則返回False(理論上效率較高)
這兩個返回值皆為 bool
範例程式碼如下
```java=
public class t3 {
public static void main(String[] args){
int a=0, b=1;
System.out.printf("%b\n", (a+1==b && a==b));
System.out.printf("%b\n", (a+1==b & a==b));
System.out.printf("%b\n", (a+1==b || a==b));
System.out.printf("%b\n", (a+1==b | a==b));
}
}
```
輸出值
```java=
false
false
true
true
```
:::
---
## 2. if-else
:::success
格式跟 C 一樣
範例程式碼如下
```java=
import java.util.Scanner;
public class t4 {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int a,b;
a=input.nextInt();
b=input.nextInt();
if(a>b){
System.out.println("a > b");
}else{
System.out.println("a < b");
}
}
}
```
輸入輸出值
```java=
10 -> 輸入1
20 -> 輸入2
a < b -> 輸出
```
:::
## 練習-1
:::info
### 1. 判斷數是否整除
給予3個數x, y, num
計算num是否能同時被x和y整除?
如果可輸出"Y"
否則輸出"N"
1 <= x, y, num <= 10^5
---
input-1
```=
3
7
42
```
output-1
```=
Y
```
---
input-2
```=
4
7
42
```
output-2
```=
N
```
:::spoiler
```java=
import java.util.Scanner;
public class p1 {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int x = input.nextInt();
int y = input.nextInt();
int num = input.nextInt();
if(num%x==0 && num%y==0){
System.out.println("Y");
}else{
System.out.println("N");
}
}
}
```
:::
:::info
### 2. 不小心 or 故意
依序輸入a, b, c, d
根據符合以下算式的數量
1. b整除a
2. d整除c
3. a和c相差=1
4. b和d相差<3
5. 四個數相乘為正數
輸出以下內容
0. 故意的
1. 故意不小心的
2. 不小心故意的
3. 不小心的
4. 正常的
5. 完美的
---
input
```=
9 -> a
3 -> b
8 -> c
4 -> d
```
output
```=
完美的
```
:::spoiler
```java=
import java.util.Scanner;
public class p2 {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int a = input.nextInt();
int b = input.nextInt();
int c = input.nextInt();
int d = input.nextInt();
int s = 0;
if(a%b==0){
s++;
}
if(c%d==0){
s++;
}
if((a-c)==-1 || (a-c)==1){
s++;
}
if((b-d)>=-3 && (b-d)<=3){
s++;
}
if(a*b*c*d>=0){
s++;
}
switch (s) {
case 0:
System.out.println("故意的");
break;
case 1:
System.out.println("故意不小心的");
break;
case 2:
System.out.println("不小心故意的");
break;
case 3:
System.out.println("不小心的");
break;
case 4:
System.out.println("正常的");
break;
case 5:
System.out.println("完美的");
break;
}
}
}
```
:::
---
## 3. for
:::success
格式跟 C 一樣
>for(初始變數 ; 條件式 ; 變數更新式){...}
程式每一次執行
都會執行一次「變數更新式」
然後根據「條件式」,判斷是否還要執行下去
範例程式碼如下
```java=
public class t5 {
public static void main(String[] args){
int a=1;
for(int i=0; i<5; i++){
a*=2;
}
System.out.println(a);
}
}
```
輸出值
```=
32
```
以上程式是將 a * 2 執行 5 次
:::
## 練習-2
:::info
### 1. 找最大值
第一行 target
代表接下來有 target 個大於0之正整數
輸出這些數的最大值
1 <= target <= 10^5
---
input-1
```=
5 -> target
2
4
6
8
2
```
output-1
```=
8
```
---
input-2
```=
10 -> target
2
4
10
8
10
77
14
19
109
11
```
output-2
```=
109
```
:::spoiler
```java=
import java.util.Scanner;
public class p3 {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int target = input.nextInt();
int max=-9999999, a;
for(int i=0; i<target; i++){
a=input.nextInt();
if(a>max){
max=a;
}
}
System.out.println(max);
}
}
```
:::
:::info
### 2. 計算式
第一行 target
第二行 num
將 num 執行 target 次以下算法
若 num 是偶數, num/2
否則 num*3-1
輸出 num
1 <= target, num <= 10^8
---
input-1
```=
3
10
```
output-1
```=
7
```
---
input-2
```=
9
65535
```
output-2
```=
27647
```
:::spoiler
```java=
import java.util.Scanner;
public class p4 {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int target = input.nextInt();
int num = input.nextInt();
for(int i=0; i<target; i++){
if(num%2==0){
num/=2;
}else{
num=num*3-1;
}
}
System.out.println(num);
}
}
```
:::
---
## 4. while
:::success
格式跟 C 一樣
>while(條件式){...}
只要條件式成立,程式就會一直執行下去
範例程式碼如下
```java=
import java.util.Scanner;
public class t7 {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int a=input.nextInt();
while(a<10){
a=input.nextInt();
}
System.out.println(a);
}
}
```
輸入輸出值
```=
1
2
3
7
8
9
10
10 -> 輸出
```
以上程式是不斷判斷a是否>=10
如果<10,則繼續輸入,直到a>=10為止
:::
## 練習-3
:::info
### 1. 計算執行次數
給定 num1, num2, num3
計算 num1 乘 num2 多少次才會 >= num3
10^-5 <= num1 <= 10
1 < num2 <= 10
1 <= num3 <= 10^8
注意:由於本題牽涉到小數運算,因此請用float
---
input-1
```=
0.1
2
1024
```
output-1
```=
14
```
---
input-2
```=
0.001
1.001
65535
```
output-2
```=
18007
```
:::spoiler
```java=
import java.util.Scanner;
public class p5 {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
float num1 = input.nextFloat();
float num2 = input.nextFloat();
float num3 = input.nextFloat();
int i = 0;
while(num1<num3){
num1*=num2;
i++;
}
System.out.println(i);
}
}
```
:::
:::info
### 2. 行走座標(困難)
相信大家應該都看過一些市面上的2D遊戲,這些遊戲的角色一般都是透過WASD來控制其走向
假設你站在一個坐標系的原點 (0, 0) 上,想從原點出發進行一系列移動
你可以向上(w)、向下(s)、向左(a)、向右(d)進行移動
每次移動,你會前進一個單位距離
現在你打出了一段指令序列
指令包括:
"w" 表示向上移動(y+1)
"s" 表示向下移動(y-1)
"a" 表示向左移動(x-1)
"d" 表示向右移動(x+1)
請計算回到原點所花費的總步數
資料為無限的,保證一定會返回原點
每筆資料均為 "w"、"s"、"a"、"d" 任一值
提示:
字串比對要用
`字串名稱.equals(字串)`
不可用`==`
---
input-1
```=
d
d
a
w
s
a -> 回到原點,程式結束,以下輸入可忽略
w
w
w
a
w
w
a
w
w
d
s
d
s
a
```
output-1
```=
6
```
---
input-2
```=
a
w
w
s
w
s
d
a
d
s -> 回到原點,程式結束,以下輸入可忽略
d
a
d
w
w
w
s
w
s
w
a
a
s
s
s
d
s
a
d
s
```
output-2
```=
10
```
:::spoiler
```java=
import java.util.Scanner;
public class p6 {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int x=0, y=0;
String a = input.nextLine();
int i = 1;
if(a.equals("w")){
y+=1;
}else if(a.equals("s")){
y-=1;
}else if(a.equals("a")){
x-=1;
}else{
x+=1;
}
while(!(x==0 && y==0)){
a = input.nextLine();
if(a.equals("w")){
y+=1;
}else if(a.equals("s")){
y-=1;
}else if(a.equals("a")){
x-=1;
}else{
x+=1;
}
i++;
}
System.out.println(i);
}
}
```
:::
---
## 5. List
:::success
List一般用來存儲多個「相同類型」的數據
創建較為麻煩,需要 import 兩個函式
```java=
import java.util.List;
import java.util.ArrayList;
```
---
創建時,需要用以下程式(建議背下來)
```java=+
List<Integer> list_1 = new ArrayList<>();
```
這樣就是建好一個空 int 字串了
---
除了 int,也可以創建 float 和 string
範例如下
```java=+
List<Float> list_2 = new ArrayList<>();
List<String> list_3 = new ArrayList<>();
```
以上三個是最常用的 List
---
List 的增加要用 add
```java=+
list_1.add(input.nextInt()); //int
list_2.add(input.nextFloat()); //float
list_3.add(input.nextLine()); //string
```
---
如果要調用 List 內的某一值,要用 get
```java=+
int a=list_1.get(0); //調用list_1第0個值
```
---
修改某一值用 set
```java=+
list_3.set(0, "sleep"); //將list_3的值更改為"sleep"
```
---
刪除某一值用 remove
```java=+
list_2.remove(0); //刪掉list_2的第0個值
```
刪除後,後面的值會全部往前一位
---
如果要遍歷整個 List,可以用 for
```java=+
for(int i : list_1){...}
```
i 的值會從 list_1 的第0個,照順序跑到 list_1 的最後一個
---
測量 list 的大小,要用 size
```java=+
int a=list_1.size(); //需注意,返回值是 int
```
---
以上就是 list 的常用操作
範例程式碼如下
```java=
import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;
public class t10 {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
List<Integer> list_1 = new ArrayList<>();
List<Float> list_2 = new ArrayList<>();
List<String> list_3 = new ArrayList<>();
//--------------------------------------------------------------------------
for(int i=0; i<3; i++){
System.out.println("int:");
list_1.add(input.nextInt());
System.out.println("float:");
list_2.add(input.nextFloat());
input.nextLine();
/*
上面這行是用來清除換行,因為 nextLine 本質是接收所有值(包括換行\n)
所以要在輸入前,先用 nextLine 接收一次 \n
已保證接下來的輸入是正確的
*/
System.out.println("string:");
list_3.add(input.nextLine());
}
//-------------------------------------------------------------------------
for(int i : list_1){ //依序遍歷list_1
System.out.println(i);
}
System.out.println(list_1);
int a=list_1.get(0); //調用list_1第0個值
int b=list_1.size(); //需注意,返回值是 int
System.out.printf("a = %d, b = %d\n", a, b);
//--------------------------------------------------------------------------
for(float j : list_2){ //依序遍歷list_2
System.out.println(j);
}
System.out.println(list_2);
list_2.remove(0); //刪掉list_2的第0個值
System.out.println(list_2);
//--------------------------------------------------------------------------
for(String k : list_3){ //依序遍歷list_3
System.out.println(k);
}
System.out.println(list_3);
list_3.set(0, "sleep"); //將list_3的值更改為"sleep"
System.out.println(list_3);
}
}
```
大部分 List 會用到的,都有寫進去了
因此程式碼很長,建議慢慢看
:::
:::warning
本章的介紹就到這邊
一般學到這裡後
你應該就對數據結構有些微的了解了
接下來就是去 Leetcode 不斷的刷題
透過不斷的刷題,來鞏固自己的能力
Leetcode 刷過60題後,就可以開始學演算法了
如果諸位想學演算法的話
我也可以再做幾篇有關演算法的筆記供諸位參考
以上
:::
## 綜合練習
:::info
### 1. 兩數之和
給定
1. 整數 n
2. 單調遞增的整數 List
3. 整數 t
n 代表 List 的長度
試求 List 內,任兩數相加 = t 的方案數
1 <= List[n]
t / 2 < List[-1]
t % 2 = 1
以input-1為例
n = 6
List = [ 1 , 2 , 3 , 3 , 4 , 5 ]
t = 5
共計 3 個方案數
分別為
1(0), 4(4)
2(1), 3(2)
2(1), 3(3)
括號內數字代表位址
提示:
這題要用2個for迴圈做
---
input-1
```=
6 -> n
1
2
3
3
4
5
5 -> t
```
output-1
```=
3
```
---
input-2
```=
10 -> n
1
1
2
4
4
5
7
7
7
8
5 -> t
```
output-2
```=
4
```
:::spoiler
```java=
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class p7 {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int n = input.nextInt();
List<Integer> list = new ArrayList<>();
int i;
for(i=0; i<n; i++){
list.add(input.nextInt());
}
int t = input.nextInt();
int s = 0, k;
for(i=0; i<n; i++){
for(k=i+1; k<n; k++){
if(list.get(i)+list.get(k)==t){
s++;
}
}
}
System.out.println(s);
}
}
```
:::
:::info
### 2. List 的三角和
給定
1. n
2. list
n 代表 list 的長度
list 的每一個值都介於 0 ~ 9 之間
重複執行以下操作:
1. 將每個鄰近的數字相加並 %10,產生新 list
2. 如果 list 只有一個數字則結束,輸出最後的值
3. 否則重複步驟 1
如下圖

---
input-1
```=
5 -> n
1
2
3
4
5
```
output-1
```=
8
```
---
input-2
```=
10 -> n
6
8
2
7
7
6
7
7
1
4
```
output-2
```=
9
```
:::spoiler
```java=
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class p8 {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
List<Integer> list_1 = new ArrayList<>();
List<Integer> list_2 = new ArrayList<>();
int n = input.nextInt();
int i;
for(i=0; i<n; i++){
list_1.add(input.nextInt());
}
int len = list_1.size();
while(len>1){
for(i=0; i<len-1; i++){
list_2.add((list_1.get(i)+list_1.get(i+1))%10);
}
list_1.clear();
list_1.addAll(list_2);
list_2.clear();
len = list_1.size();
}
System.out.println(list_1.get(0));
}
}
```
:::