---
# System prepended metadata

title: 'Static Single-level Array (and apply to Loop, Function & Recursion)'
tags: [C Language]

---

Static Single-level Array (and apply to **Loop**, **Function** & **Recursion**)
===

Introduction
---
**Array** can reacord a sequence of variables and access certain variable by indexing.

Declaration
---
To declaration of an array, we need to give this array what type of element it should record so that array will **access** or **modify** the array in unit of this type.

If we want to allocate a **static array**, we should specify a **array size** to this array, because the array size can **not** be modified during the execution of the program.




```c=
#include<stdio.h>

int main(){
    
    // specify size 100 to array, and array can be any type
    int int_arr[100];   // int array
    char char_arr[100]; // char array

    return 0;
}
```



:::success
Hint:
We usually initialize all **bits** in an array to **0** when we declare it by using this:
```c=
int arr[100] = {0};
```
:::

:::warning
Notice:

1. Whereas, we usually have a changable size in every request, so we nee to give the size as big as possible.
2. The spcification of size for a  array would be done during the **compile-time**, therefore, we must declare the size before execution.

    The declaration of ar will not be accepted in **C language**:
    ```c=
    #include<stdio.h>

    int main(){
        int n;
        scanf("%d", &n);
        int arr[n]; // we use a variable as the size of a array
                    // which is unacceptable.
                    // because value of variable n is given during the execution
        return 0;
    }
    ```

    If we use **define** a number at first and using this number as the size of a array, this situation is acceptable, because it would be done during the **compile-time**.
    ```c=
    #include<stdio.h>

    #define SIZE 10    // define a numbber

    int main(){
        int arr[SIZE]; // acceptable
        return 0;
    }
    ```

    However, this can be resolved by using **dynamic allocation**, and some late version of **C++** can support this kind of form.
:::

Operation
---

### Indexing

We can **access** or **modify** certain element in the array by using **indexing**.

And the index in an array counted from **0** to **size - 1**, total **size** elements.

When we give a index to a array, it will return a variable in that index in type which we specify it when declaration.

#### Usage

```c=
#include<stdio.h>

int main(){

    int arr[3] = {0};

    arr[0] = 1;
    arr[2] = 10;

    printf("%d ", arr[0]);
    printf("%d ", arr[1]);
    printf("%d\n", arr[2]);
    return 0;
}
```

Indexing can also be combined with **for loop**, which is a very common combination.

ex.
```c=
#include<stdio.h>

int main(){

    int arr[10] = {0};

    for(int i=0;i<10;i++){     // assing 0 ~ 9 to arr[0~9]
        arr[i] = i;
    }

    for(int i=0;i<10;i++){
        printf("%d ", arr[i]); //print out arr[0~9]
    }
    printf("\n");

    return 0;
}
```

:::info
Hint:
We can to input or output a **string** using "char" array, and program use '\0' to determine the last element of string, in other words, if '\0' at index i, arr[0~(i-1)] is the string.

We can do like this:
```c=
char arr[100]; // total length can not exceed 99                    //because we need to preserve 1 unit for '\0'
scanf("%s", arr);
printf("%s", arr);
```
:::

Addressing
---

In a array, we can acces it by using address, assume there is a array called $arr$.

Assume there is a index: $i$, value of **arr + i** equals to **&arr[i]**(address of arr[i]).

```c=
#include<stdio.h>

int main(){
    int arr[100] = {0}; // 100 element in this array
                        // We initialize it to all 0

    // flag: %p stands for "address"
    printf("arr    : %p\n", arr);
    printf("&arr[0]: %p\n", &arr[0]);
    printf("\n");
    printf("arr + 1: %p\n", arr + 1);
    printf("&arr[1]: %p\n", &arr[1]);

    return 0;
}
```

Practice
---

1. Prefix, given a array size n, followd by n numbers stand for n elements in the array, please find the prefix array of original one.

```c=
#include<stdio.h>

#define SIZE 1000

int main(){
    int n;
    int arr[SIZE];

    scanf("%d", &n);
    for(int i=0;i<n;i++){
        scanf("%d", &arr[i]);
    }

    for(int i = 1;i<n;i++){
        arr[i] += arr[i-1];
    }
    
    for(int i = 0;i<n;i++){
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}
```

:::info
Remember:
Prefix has a very important propertiy, if you construct a prefix array of a array, then you can calculate the interval sum very quickly.

Assume there is a array arr[n], and the prefix array p_arr[n] of original one.

Because,
p_arr[i] = arr[0] + arr[1] + ... + arr[i]
Therefore, there are 2 integer a, b, and a < b
p_arr[b] - p_arr[a] = arr[a + 1] + arr[a + 2] + ... + arr[b]


:::

2. Find maximum in a array.
    Given a array size n, followd by n numbers stand for n elements in the array, please find the **index** of max number and the **max number** in this array.
```c=
#include<stdio.h>

#define SIZE 1000

int main(){
    int n;
    int arr[SIZE];

    scanf("%d", &n);
    for(int i=0;i<n;i++){
        scanf("%d", &arr[i]);
    }

    int index = -1, maxNum;
    for(int i=0;i<n;i++){
        if(index == -1){
            index = i;
            maxNum = arr[i];
        }else if(maxNum < arr[i]){
            index = i;
            maxNum = arr[i];
        }
    }

    printf("%d %d", index, maxNum);
    return 0;
}
```

3. Find maximum interval of a array.
    Given a array size n, followd by n numbers stand for n numbers in the array, please find the interval [x, y] that has maximun sum and the value of maximum sum in this array.
```c=
???
```

4. Cut the trees
input a n representing the number of trees, followed by n integer represent the height of n trees and those tree has their index 0~n-1 in order, and we want construct that the height of trees should keep increasing according to its index, therefore we traverse from index 0 to n-1, if the height of tree is lower than or eauql to previous trees, then cut it off.
Please ouput the trees have not been cut off.

    ex.
    input:
    6
    1 7 3 5 9
    ouput:
    1 7 9


Time Complexity
---
[Time Complixity---Wiki](https://zh.wikipedia.org/zh-tw/%E6%97%B6%E9%97%B4%E5%A4%8D%E6%9D%82%E5%BA%A6)

### BIG O notation

If highest power of $x$ in $g(x)$ is $a$, then $g(x) \in O(x^a)$


O($n^2$) Sorting Algorithm
---

1. Insertion Sort
    Insertion sort is a sort algorithm that is very **intuitive** and it is a sort method like how we organize our card when we play pockers.
    Assume there is a set of cards unorganized.
    
    Here is the rules :
    1. Every time we get a card in the set, compare it and put it in to the right place in our hand.
    2. Repeat **step 1** until all cards are collected.

### 2 Array:
```c=
#include<stdio.h>

#define SIZE 1000

int main(){
    int n;
    int arr[SIZE], sorted[SIZE];

    scanf("%d", &n);

    // Initialize the array
    for(int i=0;i<n;i++){
        scanf("%d", &arr[i]);
    }

    int sortedSize = 0;
    // Sort from small to large
    // Start insertion sort
    for(int i=0;i<n;i++){
        int putPosition = 0;
        for(int j = 0;j < sortedSize;j++){
            if(sorted[j] <= arr[i]){
                putPosition++;
            }else{
                break;
            }
        }

        // Now we got right putPosition
        // Move all card after putPotion in sorted array 1 unit back
        for(int j = n-1;j >= putPosition;j--){
            sorted[j + 1] = sorted[j];
        }

        // We put now number to right position
        sorted[putPosition] = arr[i];
        sortedSize++; // update sorted size
    }
    
    // Print array out
    for(int i = 0;i<n;i++){
        printf("%d ", sorted[i]);
    }
    printf("\n");
    return 0;
}
```

2. Bubble Sort
    Bubble Sort is also a sorting algorithm to sort a unorganized seqeuence. The motivation of this sorting algorithm is that, assuming we have a array arr[n], and if we can put most i-th biggest number to i-th position, then after n rounds, we can sort this array in the right order.
    
    Here is the sorting rules:
    1. Start at the beginning of the list.
    2. Compare each pair of adjacent elements.
        - If the elements are in the wrong order (out of place), swap them.
    3. Continue this process from the beginning of the list to the end.
        - After the first pass, the largest element is guaranteed to be in its correct position at the end of the list.
        - After subsequent passes, the next largest elements are placed in their correct positions.
    4. Repeat the process for the remaining unsorted elements until the entire list is sorted.

Code:
```c=
#include<stdio.h>

#define SIZE 1000

int main(){
    int n;
    int arr[SIZE];

    scanf("%d", &n);

    // Initialize the array
    for(int i = 0;i < n;i++){
        scanf("%d", arr[i]);
    }

    // Sort from small to large
    // Start insertion sort
    for(int i = n-2;i >= 0;i--){
        for(int j = 0;j <= i;j++){
            if(arr[j] > arr[j+1]){
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }

    // Print array out
    for(int i = 0;i < n;i++){
        printf("%d ", arr[i]);
    }
    printf("\n");

    return 0;
}
```

### HW
1. Using **array** and **for loop** to implement **Selection Sort**(ps. You need to realize what is selection sort first)
```c=
#include<stdio.h>

int main(){
    int n;
    int arr[10000];
    scanf("%d", &n);
    for(int i=0;i<n;i++){
        scanf("%d", &arr[i]);
    }

    for(int i=0;i<n-2;i++){
        int minIndex;
        for(int j=i;j<n;j++){
            if(j == i){
                minIndex = j;
            }else if(arr[j] < arr[minIndex]){
                minIndex = j;
            }
        }
    }

    for(int i=0;i<n;i++){
        printf("%d", arr[i]);
    }
    printf("\n");

    return 0;
}
```
2. [大數運算](https://zerojudge.tw/ShowProblem?problemid=a021)
```c=
#include<stdio.h>
#include<string.h>

int main(){
    char n1[501], n2[501];
    char op;

    scanf("%s %c %s", n1, &op, n2);

    int size1 = strlen(n1);
    int size2 = strlen(n2);
    int m, length;

    if(size1 > size2){
        length = size1;
        m = size1 - size2;
        for(int i = size2;i >= 0;i--){
            n2[i + m] = n2[i];
        }
        for(int i = 0;i < m;i++){
            n2[i] = 0;
        }
    }else{
        length = size2;
        m = size2 - size1;
        for(int i = size1;i >= 0;i--){
            n1[i + m] = n1[i];
        }
        for(int i = 0;i < m;i++){
            n1[i] = 0;
        }
    }

    int sum[501];

    if(op == '+'){
        int carry = 0;
        for(int i = length -1;i >= 0;i--){
            sum[i] = ((n1[i] - '0') + (n2[i] - '0') + carry)%10;
            if((n1[i] - '0') + (n2[i] - '0') + carry >= 10){
                carry = 1;
            }else{
                carry = 0;
            }
        }
        if(carry == 1) printf("%d", carry);
        for(int i = 0;i<length;i++){
            printf("%d", sum[i]);
        }
    }else if(op == '-'){
        
    }

    printf("\n");
    return 0;
}

//  0028758392\0
//+ 1874022485\0


// 28758392 -> sizeof(long) - sizeof(short)
```
3. [合併社辦](https://zerojudge.tw/ShowProblem?problemid=d456)
```c=
#include<stdio.h>
#include<string.h>

int main(){
    char classes[10000];
    char a, b;

    scanf("%s\n%c%c", classes, &a, &b);
    // printf("%s %c %c\n", classes, a, b);

    int size = strlen(classes);
    int loc1, loc2;
    for(int i=0;i<size;i++){
        if(classes[i] == a) loc1 = i;
        if(classes[i] == b) loc2 = i;
    }

    if(loc1 > loc2){
        int temp = loc1;
        loc1 = loc2;
        loc2 = temp;
    }

    for(int i = 0;i<size;i++){
        if(i<=loc1 || i>=loc2){
            printf("%c", classes[i]);
        }
    }
    printf("\n");
    for(int i = loc1 + 1;i <= loc2 - 1;i++){
        printf("%c", classes[i]);
    }
    printf("\n");

    return 0;
}
```

Apply Array to Recursion
---

### Permutation

We can ustilize the arr and recurssion to contrcute the permutation of numbers.

```c=
#include<stdio.h>

#define MAX_SIZE 1000

void arr_permute(int *arr, int sta, int end, int size){
    if(sta == end){
        for(int i=0;i<size;i++){
            printf("%d ", arr[i]);
        }
        printf("\n");
        return;
    }
    
    // total end - sta +1 times
    for(int i=sta;i<=end;i++){
        arr_permute(arr, sta+1, end, size); // we fix arr[sta] and permutate from arr[sta + 1] ~ arr[end]

        // move all ahead
        int temp = arr[sta];
        for(int j=sta;j<=end-1;j++){
            arr[j] = arr[j+1];
        }
        arr[end] = temp;
    }
}

int main(){
    int n;
    int arr[MAX_SIZE];

    scanf("%d", &n);
    for(int i=0;i<n;i++){
        scanf("%d", &arr[i]);
    }

    arr_permute(arr, 0, n-1, n); // pass 0, n-1 to permute arr[0]~arr[n-1]

    return 0;
}
```

### Merge Sort O(nlogn)

Merge Sort is a popular sorting algorithm that follows the **divide-and-conquer** paradigm. The basic idea of Merge Sort is to divide the unsorted list into n sublists, each containing one element (making them inherently sorted), and then repeatedly merge sublists to produce new sorted sublists until only one sublist remains.



#### What is merge?

2 **sorted array**, we can merge it into **one array** with same **sorted rules**.
And we can do that in O(n).

ex.

arr1 = 1 4 8 9
arr2 = 2 6 11 16 22

merge them into
arr = 1 2 4 6 8 9 11 16 22

```c=
void merge(int *des, int *arr1, int size1, int *arr2, int size2){ // merge arr1 and arr2 to des
    int size = size1 + size2;
    int index1 = 0, index2 = 0, index = 0;
    while(index < size){
        if(index2 == size2){
            des[index] = arr1[index1];
            index1++;
            index++;
            continue;
        }
        if(index1 == size1){
            des[index] = arr2[index2];
            index2++;
            index++;
            continue;
        }

        if(arr1[index1] < arr2[index2]){
            des[index] = arr1[index1];
            index1++;
            index++;
        }else{
            des[index] = arr2[index2];
            index2++;
            index++;
        }
    }
}
```

#### Merge Sort
By applying the tech of divide and conquer, we can accomplish sorting in **O(nlogn)**
![image](https://hackmd.io/_uploads/r1au1XkqT.png)


```c=
#include<stdio.h>

#define MAX_SIZE 100000

void merge(int *des, int *arr1, int size1, int *arr2, int size2){ // merge arr1 and arr2 to des
    int size = size1 + size2;
    int index1 = 0, index2 = 0, index = 0;
    while(index < size){
        if(index2 == size2){
            des[index] = arr1[index1];
            index1++;
            index++;
            continue;
        }
        if(index1 == size1){
            des[index] = arr2[index2];
            index2++;
            index++;
            continue;
        }

        if(arr1[index1] < arr2[index2]){
            des[index] = arr1[index1];
            index1++;
            index++;
        }else{
            des[index] = arr2[index2];
            index2++;
            index++;
        }
    }
}

// divdie and conquer
void merge_sort(int *arr, int sta, int end){
    if(sta >= end){
        return;
    }

    int mid = sta + (end - sta) / 2; // we should notice that we may divide negative number
    
    // divide
    merge_sort(arr, sta, mid);   // sort sta~mid
    merge_sort(arr, mid+1, end); // sort (mid+1)~end

    int size1 = mid - sta + 1, size2 = end - (mid + 1) +1;
    
    // conquer
    int temp[MAX_SIZE];
    merge(temp, arr+sta, size1, arr+mid+1, size2);

    for(int i=sta;i<=end;i++){
        arr[i] = temp[i-sta];
    }
}

int main(){

    int n;
    int arr[MAX_SIZE];

    scanf("%d", &n);
    for(int i=0;i<n;i++){
        scanf("%d", &arr[i]);
    }

    merge_sort(arr, 0, n-1);

    for(int i=0;i<n;i++){
        printf("%d ", arr[i]);
    }
    printf("\n");

    return 0;
}
```

Practice
---
Below practices only test your skill about recursion, do not try to **AC** the prolem(but if you have so many time...), since those problem involves some advanced knowledge and it will cost so much time.

[d443. 10497 - Sweet Child Makes Trouble](https://zerojudge.tw/ShowProblem?problemid=d443)

[f168. m4a2-分配寶物(Treasure)](https://zerojudge.tw/ShowProblem?problemid=f168)

[北門街](https://zerojudge.tw/ShowProblem?problemid=b576) (recursion with no array can solve this problem, but exceed **TIME LIMIT** array can accerlerate it.)
