(資料結構程式碼,總結,自我思考)=> { return 個人學習筆記; } 【To be continued~】

Lucas~發表於2024-04-20

俗話說 “學而不思則罔”,是時候複習和整理一下自己先前的學習歷程了!

Chapter-One

《BinarySearch》

public static int binarySearch (int[] a, int target) {
        int i = 0, j = a.length - 1;
        
        while (i <= j) {
            int m = (i + j) >>> 1; // 求中位數,但是是用位運算子的方式,相對於除法,這種方式更加高效
           if (target < a[m]) {
               j = m - 1; // 如果找到的目標數小於中位數,則在中位數的左邊開始找起
           } else if (a[m] < target){
               i = m + 1; // 如果找到的目標數大於中位數,則在中位數的右邊開始找起
           } else {
               return m; // 找到則直接返回改數值在陣列中的索引的值
           }
        }
        return -1;  /* 沒有找到則直接返回-1,當然這裡選擇丟擲異常(並提示異常資訊,個人覺得對使用者體驗更加好 如: )  throw new RuntimeException("目標數值不在陣列中"); */
    }

自問自答

   問:為什麼while的條件中 i <= j 而不是 [instead of] i < j ?
   答:1. 首先,顧名思義,前面的條件會比後面的條件多執行一次。
      2. 那如果當 target == i == j 的時候呢,那少去的這一次就會因為不滿足while條件直接退出迴圈了,然後放回直接沒有找到的該目標值。因此為了避免這種情況的發生,我們應該加上等於號。

《DynamicArray》

import java.util.Arrays;
import java.util.Iterator;
import java.util.function.Consumer;
import java.util.stream.IntStream;

public class DynamicArray implements Iterable<Integer> {
    private int size = 0; // 陣列中儲存元素的個數
    private int capacity = 8; // 陣列的容量大小
    private int[] array = {};


    public void addLast(int element) { // 在陣列的尾部新增元素
//        array[size] = element;
//        size++;   the original thought
        add(size,element);
    }

    public void add(int index, int element) {
        checkAndGrow(); // 判斷需要動態擴容的模式
        if (index >=0 && index < size) {
            System.arraycopy(array, index,
                    array, index + 1, size - index); // 使用java自帶的內建API,進行陣列的複製
        } else if (index < 0) {
            throw new RuntimeException("index typing wrong, retry again please!");
        }
        array[index] = element;// 指定的位置對元素進行新增
        size++; // 更新陣列元素個數
    }

    private void checkAndGrow() {
        //check
        if (size == 0) {
            array = new int[capacity];// 等於0時,預設初始化的容量
        } else if (size == capacity) {
            capacity += capacity >> 1; // 擴容1.5倍
            int[] newArray = new int[capacity];
            System.arraycopy(array, 0,
                    newArray, 0, size); // 陣列複製
            array = newArray;
        }
    }

    public int get(int index) { // 獲取陣列中指定的元素
        return array[index];
    }

    public void foreach(Consumer<Integer> consumer) { //遍歷陣列元素
        for (int i = 0; i < size; i++) {
            consumer.accept(array[i]);
        }
    }

    @Override
    public Iterator<Integer> iterator() { // 迭代器
        return new Iterator<Integer>() {
            int i = 0;
            @Override
            public boolean hasNext() { // 判斷是否有下一個元素
                return i < size;
            }

            @Override
            public Integer next() { // 返回當前元素,並且指標向後面移動一位
                return array[i++];
            }
        };

    }


    public IntStream stream() { // 將陣列轉成int位元組流
        return IntStream.of(Arrays.copyOfRange(array,0,size)); //[0,size)
    }


    public int remove(int index) { //移除指定的 範圍:[0,size)
        int removed = array[index];
        if (index < size - 1) {
                System.arraycopy(array, index + 1,
                        array, index, size - index - 1);
            }
        size--;
        return removed;
    }
}

自問自答

 	問:箭頭函式在這裡的用法?
 	答 1. foreach方法中定義的引數,類似一個集合的作用,把陣列中所有的遍歷之後的元素都存起來了
 	   2. 因此在呼叫的階段,我們直接傳一個(whatever)形參,然後在 {程式碼塊中},我們可以對該引數做任何我們想做的事情或者實現想要實現的功能。
 	   3. 相當於是,內部收集到了這個陣列的值,但是這個值有什麼用途,留給呼叫這個方法的使用者去決定了。

在這裡插入圖片描述
example

@Test
    public void test2() {
        DynamicArray dynamicArray = new DynamicArray();
        AtomicInteger sum = new AtomicInteger(); // 把變數設定為原子狀態的Integer包裝型別
        dynamicArray.addLast(1);
        dynamicArray.addLast(2);
        dynamicArray.addLast(3);
        dynamicArray.addLast(4);

        dynamicArray.forEach((element)->{
            sum.addAndGet(element);// 對element的所有元素進行相加, 這裡返回值是int,但是我選擇不接收。
        });

        System.out.println(sum.get()); //輸出累加的結果!
    }

執行結果

未完待續······

相關文章