---
###### tags: `程式筆記` `web111a` `JavaScript`
---
# 洪老師練習題
:::info
作業二開始我是用javascript寫的~
:::
## 作業一
### 九九乘法
### 三角形
#### 直角三角
* 正序(由小到大)
* 倒序(由大到小):固定數-i
```csharp=
for (i = 1; i <= n; i++)
{
for (j = 1; j <= n - i + 1; j++)
{
Console.Write($"X{t}");
}
Console.WriteLine();
}
```
#### 正三角
先倒序三角形印空白,在正序三角形
```csharp=
for (i = 1; i <= n; i++)
{
for (j = 1; j <= n - i; j++) Console.Write(t);
for (k = 1; k <= i; k++) Console.Write(s+t);
Console.WriteLine("");
}
```
#### 倒三角
```csharp=
for (i = 1; i <= n; i++)
{
for (j = 1; j <= i - 1; j++) Console.Write(t);
for (k = 1; k <= n - i + 1; k++) Console.Write(s+t);
Console.WriteLine("");
}
```
### 菱形
#### 兩個`for`
先印邊長正三角形、在印邊長-1倒三角形
```csharp=
...
for (i = 1; i <= n; i++)
{
for (j = 1; j <= n - i; j++) Console.Write(" ");
for (k = 1; k <= i; k++) Console.Write("* ");
Console.WriteLine("");
}
for (i = 1; i <= n; i++)
{
for (j = 1; j <= i; j++) Console.Write(" ");
for (k = 1; k <= n - i; k++) Console.Write("* ");
Console.WriteLine("");
}
```
output:
```shell=
請輸入邊長:4
請輸入要畫的圖形:(1)正三角、(2)倒三角、(3)菱形:3
*
* *
* * *
* * * *
* * *
* *
*
```
#### 一個`for`
`k`:定位、`x`:每行的*數
```csharp=
for (i = 1; i <= 2 * n - 1; i++)
{
for (j = 1; j <= 2 * n - 1; j++)
{
// k = 5, 4, 3, 2, 1, 2, 3, 4, 5...
k = i <= n ? n - i + 1 : i - n + 1;
if (j >= k && j < k + x)
{
Console.Write(s);
}
else
{
Console.Write(t);
}
}
// x = 1,3,5,7,9,7,5,3,1
x = i < n ? x + 2 : x - 2;
Console.WriteLine();
}
```
## 遞迴
* 它是一個方法,一直不斷的呼叫自己,直到某些條件被滿足因而停止。
* 簡潔程式碼,易讀性高
* 效能較差
### 作法
* 寫遞迴函式,必須要先設定好遞迴終止條件
* 我們寫的遞迴函式,必須是要朝著遞迴終止條件收斂的,最終也必須要達成遞迴終止條件
* 遞迴產生的變數值會先暫存在 Stack 中,當條件滿足不在乎叫時,存在 Stack 的變數會先進後出(存入順序: A, B, C,取出順序: C, B, A)

:small_red_triangle:[C# 學習打卡,對遞迴的理解](https://read01.cc/article/3791353)
### 著名的費波那契數列 (fibonacci)
```csharp=
string input;
int n;
Console.Write("Enter a number: ");
input = Console.ReadLine();
int.TryParse(input, out n);
for(int i = 1; i <= n; i++)
{
Console.Write(fib(i)+"\t");
if (i % 5 == 0)
{
Console.WriteLine("");
}
}
static int fib(int n)
{
if(n==1 || n == 2)
{
return 1;
}
else
{
return fib(n - 1) + fib(n - 2);
}
}
```
輸出
```shell=
Enter a number: 15
1 1 2 3 5
8 13 21 34 55
89 144 233 377 610
```
## 作業二 Math0

:::spoiler 老師答案
### recursion

### for

:::
### Math0 第一題
題目:1 + 2 + 3 +...+ 5
```javascript=
function recursion1(num) {
let output = 0;
if (num > 1) {
output = num + recursion(num - 1);
} else {
output = 1;
}
return output;
}
```
:::spoiler for 的寫法
```javascript=
function for1(num) {
let output = 0;
for (let i = 1; i <= num; i++) {
output += i;
}
return output;
}
```
:::
### Math0 第二題
題目:1 + 1/2 + 1/3 +...+ 1/5
```javascript=
function recursion2(num) {
let output = 0;
if (num > 1) {
output = 1.0 / num + recursion2(num - 1);
} else {
output = 1;
}
return output;
}
```
:::spoiler for 的寫法
```javascript=
function for2(num) {
let output = 0;
for (let i = 1; i <= num; i++) {
output += 1.0 / i;
}
return output;
}
```
:::
### Math0 第三題
題目:1! + 2! + 3! +...+ 5!

```javascript=
function recursion3_1(num) {
let output = 0;
if (num > 1) {
output = num * recursion3_1(num - 1);
} else {
output = 1;
}
return output;
}
function recursion3(num) {
let output = 0;
if (num > 1) {
output = recursion3_1(num) + recursion3(num - 1);
} else {
output = 1;
}
return output;
}
```
:::spoiler for 的寫法
```javascript=
// 加法反元素 0
// 乘法反元素 1
function for3(num) {
let output = 0;
for (let i = 1; i <= num; i++) {
let temp = 1;
for (let j = 1; j <= i; j++) {
temp *= j;
}
output += temp;
}
return output;
}
```
:::
## 作業二 Math1

### Math1 第一題
題目:1+2+3+...+到 n 項
```javascript=
function m2Recursion1(num) {
let output = 0;
if (num > 1) {
output = num + m2Recursion1(num - 1);
} else {
output = 1;
}
return output;
}
```
### Math1 第二題
題目:1+3+5+...+到 n 項
```javascript=
function m2Recursion2(num) {
let output = 0;
if (num > 1) {
output = 2 * num - 1 + m2Recursion2(num - 1);
} else {
output = 1;
}
return output;
}
```
### Math1 第三題
題目:2+4+6+...+到 n 項
```javascript=
function m2Recursion3(num) {
let output = 0;
if (num > 1) {
output = 2 * num + m2Recursion3(num - 1);
} else {
output = 2;
}
return output;
}
```
### Math1 第四題
題目:1/1 + 1/(1+2) + 1/(1+2+3) +...+到 n 項
:::info
也可以用 Math0 第三題的邏輯,其中 `R0()` 是 1+2+3 的遞迴,`R1()` 是自己
```javascript=
...
output = 1.0/R0(n) + R1(n-1)
...
```
:::
```javascript=
// 遞迴
function m2Recursion4(num) {
let output = 0;
if (num > 1) {
output = 2.0 / (num * (num + 1)) + m2Recursion4(num - 1);
} else {
output = 1;
}
return output;
}
console.log(m2Recursion4(50).toFixed(7));
```
```javascript=
// 雙迴圈
function m2For4(num) {
let output = 0;
for (let i = 1; i <= num; i++) {
let d = 0;
for (let j = 1; j <= i; j++) {
d += j;
}
output += 1.0 / d;
}
return output;
}
console.log(m2For4(50).toFixed(7));
```
發現一件事,用遞迴法的寫法不能直接在 function 內用 `.toFixed()`,但迴圈法就可以,明明 return 的都是 number。
我猜、大概、可能是,因為遞迴就是會反覆呼叫自己,可以看到以下錯誤訊息 return 了很多筆,直到最後一次為止 return 的都不是 number(我猜的啦
> 如果是 `m2Recursion4(1)` 即使 `.toFixed()` 寫在 return 也不回報錯

不過在呼叫時在 `.tofixed()` 就可以(也請這麼做)
```javascript=
m2Recursion4(50).toFixed(7);
```
### Math1 第五題
題目:1-2+3-4+5-...
```javascript=
// 遞迴
function m2Recursion5(num) {
let output = 0;
if (num > 1) {
output = Math.pow(-1, num - 1) * num + m2Recursion5(num - 1);
} else {
output = 1;
}
return output;
}
```
```javascript=
// 迴圈
function m2For5(num) {
let output = 0;
for (let i = 1; i <= num; i++) {
if (i % 2 == 1) {
output += i;
} else {
output -= i;
}
}
return output;
}
```
## 作業二 Math2

### 第一題
### 第二題
### 第三題
### 第四題
### 第五題
## 小結:Math0~2 規律
做完 Math1 有無發現遞迴公式只有一點點不一樣?

* 所以重點是找到第n項,**以下規律請背下來**
* 1+2+3+... :arrow_right: n
* 1+3+5+... :arrow_right: 2n-1
* 2+4+6+... :arrow_right: 2n
* 1 + 1/(1+2) + 1/(1+2+3) + ... :arrow_right: 2/n*(n+1)
* 1-2+3-... 正項負項:arrow_right: (-1)^n-1^*n 也可寫成 Math.pow(-1, n-1)*n
* 等差的解法:和就是梯形公式
* 上底:第一項
* 下底:第n項
* 高:n
* 還有一個小知識,梯形公式也可以化成長方形公式
* 
## 作業二 排字

---
## 待整理
## 取最大值
雖有內建語法,但面試都不會給你用,還是要自幹
```csharp=
num.Max();
num.Min();
```
## 四捨六入五成雙
上例子,取小數點後第二位,當第三位為5時,若第二位為單數則進位,雙數就捨去
## 閏年計算
* 西元年份除以4不可整除,為平年。
* 西元年份除以4可整除,且除以100不可整除,為閏年。
* 西元年份除以100可整除,且除以400不可整除,為平年
* 西元年份除以400可整除,為閏年。
## 泡沫排序法
* call by value
* call by reference