# 作業三 : 程式語言十八般武藝 > 作者:黃柏豪 > 學號:D1249756 > Email: rick22630773@gmail.com > [name=alpha lucio] > [time=Thu, Oct 12, 2023 5:45 PM] ## 前言 此為逢甲大學2023年大一計算機概論的課程作業,要求學生以不同程式語言去挑戰Leetcode的題目。 ## 目錄 [TOC] ## 所挑選的題目 ### [4.Median of Two Sorted Arrays](https://leetcode.com/problems/median-of-two-sorted-arrays/) ![](https://hackmd.io/_uploads/rJr1KUL-p.png) 編譯區預設格式(C++) ![](https://hackmd.io/_uploads/S12jKLUZ6.png) ### 解題思路與想法 以下解法是以 C++ 的想法來寫的。 在這題目中,輸入值為兩串已排列好的 Vector 整數數列,輸出值為中位數。 我決定新建一個 Vector 整數數列,用以合併兩串輸入值,再用 sort() 功能排列好。 最後用 Vector.size() 判斷是否為奇數或偶數數列,最後找出中位數所在的位置,即可算出正確答案。 ## 所用的程式語言 依照解題順序排列,從 7 開始都是看著語法教學寫的 1. C++ 2. C 3. Python 4. Java 5. C# 6. Javascript 7. Ruby 8. GO 9. Rust 10. TypeScript 11. PHP 12. Swift 13. Kotlin 14. Scala 15. Dart 16. Elixir 17. Racket ## 解答程式碼 :::spoiler C++ ```cpp= class Solution { public: double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { // 設定新的Vector存入兩串輸入值 vector<int>tmp; float ans = 0; // 當 Vector 為無空值狀態時,轉移最後數字給tmp,並消除最後一位。 while(!nums1.empty()){ tmp.push_back(nums1.back()); nums1.pop_back(); } while(!nums2.empty()){ tmp.push_back(nums2.back()); nums2.pop_back(); } // 升冪排序,準備計算中位數 sort(tmp.begin(), tmp.end()); int mid = 0; // 判斷是奇數或者偶數數列,並做計算 if(tmp.size() % 2 == 1){ mid = (tmp.size()+1)/2; ans = (float) tmp[mid-1]; }else{ mid = tmp.size()/2; ans = (float) (tmp[mid] + tmp[mid-1]) / 2; } return ans; } }; ``` ![](https://hackmd.io/_uploads/BJhPbO8-p.png) ::: :::spoiler C ```c= double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){ // 新增總長度和整數數列 int arr[ nums1Size + nums2Size ]; int len = nums1Size + nums2Size; // 將兩個輸入值數列合併,順便做排序 // i 代表 arr 陣列的位置,j 代表 nums1 陣列的位置,h 代表 nums2 陣列的位置 for(int i = 0, j = 0, h = 0 ; i < len ; i++){ // 如果其中一方已經用完了,那直接將未用盡的一方輸入進 arr if( j == nums1Size ){ arr[i] = nums2[h]; h++; continue; }else if( h == nums2Size ){ arr[i] = nums1[j]; j++; continue; } // 先輸入較小的數值進 arr if( nums1[j] <= nums2[h] ){ arr[i] = nums1[j]; j++; }else{ arr[i] = nums2[h]; h++; } } // 判斷是奇數數列或偶數數列,輸出相關的值 if( len % 2 == 0){ len /= 2; return (arr[len] + arr[len-1]) / 2.00; }else{ len = len /2; return arr[len]; } } ``` ![](https://hackmd.io/_uploads/SkU9Zd8ZT.png) ::: :::spoiler Python ```python= class Solution(object): def findMedianSortedArrays(self, nums1, nums2): """ :type nums1: List[int] :type nums2: List[int] :rtype: float """ # 新增整數數列和指標 mix_arr = [0] * (len(nums1) + len(nums2)) idx_num1 = 0 idx_num2 = 0 # 當 a 方未用完 且 ( b 方已用完 或 a 方的值 小於 b 方的值 ),輸入 a 方的值並將指標+1 for i in range (len(mix_arr)): if idx_num2 < len(nums2) and ( idx_num1 == len(nums1) or nums2[idx_num2] < nums1[idx_num1] ): mix_arr[i] = nums2[idx_num2] idx_num2 += 1 else: mix_arr[i] = nums1[idx_num1] idx_num1 += 1 # 判斷 奇數 或 偶數 數列,並做運算 if len( mix_arr ) % 2 == 1: return mix_arr[len(mix_arr) // 2] else: return (mix_arr[len(mix_arr) // 2] + mix_arr[len(mix_arr) // 2 - 1]) / 2.0 ``` ![](https://hackmd.io/_uploads/ryRS-_IZ6.png) ::: :::spoiler Java ```java= class Solution { public double findMedianSortedArrays(int[] nums1, int[] nums2) { // 取得輸入值數列的長度 int n = nums1.length; int m = nums2.length; // 創建新的數列 mix,長度為 n + m,並把輸入值存進新的數列裡 int [] mix = new int[n + m]; int k = 0; for(int i = 0 ; i < n ; i++, k++){ mix[k] = nums1[i]; } for(int i = 0 ; i < m ; i++, k++){ mix[k] = nums2[i]; } // 排序 Arrays.sort(mix); // 判斷是奇數或偶數數列,並做運算後輸出 int total = mix.length; if(total % 2 == 1){ return (double) mix[total/2]; } else { int mid1 = mix[total / 2 -1]; int mid2 = mix[total / 2]; return ((double)mid1 + (double)mid2) / 2.0; } } } ``` ![](https://hackmd.io/_uploads/rkGYZ_8Wp.png) ::: :::spoiler C# ```csharp= public class Solution { public double FindMedianSortedArrays(int[] nums1, int[] nums2) { // 取得輸入值數列的長度,並新增整數數列和指標 int n = nums1.Length; int m = nums2.Length; List<int> merged = new List<int>(); int i = 0, j = 0; // 先輸入較小的數字 while(i < n && j < m){ if(nums1[i] < nums2[j]){ merged.Add(nums1[i++]); }else{ merged.Add(nums2[j++]); } } // 因為較小的數字都被先推入 List<int> merged裡了 // 這裡只需輸入,不需要排列 while (i < n) { merged.Add(nums1[i++]); } while (j < m){ merged.Add(nums2[j++]); } // 判斷奇數or偶數數列,計算並輸出 int mid = merged.Count / 2; if(merged.Count % 2 == 0){ return (merged[mid-1] + merged[mid]) / 2.0; }else{ return merged[mid]; } } } ``` ![](https://hackmd.io/_uploads/Bk7JWO8ZT.png) ::: :::spoiler Javascript ```javascript= var findMedianSortedArrays = function(nums1, nums2) { /** * @param {number[]} nums1 * @param {number[]} nums2 * @return {number} */ // 新增整數數列和指標 let merged = []; let i = 0, j = 0; // 先輸入較小的數值 while(i < nums1.length && j < nums2.length){ if(nums1[i] < nums2[j]){ merged.push(nums1[i++]); }else{ merged.push(nums2[j++]); } } // 將剩餘的數填入 merged 裡面 while (i < nums1.length) { merged.push(nums1[i++]); } while (j < nums2.length){ merged.push(nums2[j++]); } // 判斷是否為奇數數列,做運算後輸出 let mid = Math.floor(merged.length / 2); if (merged.length % 2 === 0) { return (merged[mid-1] + merged[mid]) / 2; } else { return merged[mid]; } }; ``` ![](https://hackmd.io/_uploads/BknDEOUba.png) ::: :::spoiler Ruby ```ruby= # @param {Integer[]} nums1 # @param {Integer[]} nums2 # @return {Float} def find_median_sorted_arrays(nums1, nums2) #推入 nums1_length = nums1.length nums2_length = nums2.length i = 0 j = 0 arr = [] while(i < nums1_length and j < nums2_length) do if nums1[i] <= nums2[j] arr << nums1[i] i += 1 else arr << nums2[j] j += 1 end end while(i < nums1_length) do arr << nums1[i] i += 1 end while(j < nums2_length) do arr << nums2[j] j += 1 end #計算中間值 median = 0 low = 0 high = arr.length-1 mid = high/2 if high.odd? median = (arr[mid] + arr[mid+1]).to_f/2.to_f else median = arr[mid].to_f end return median end def sorting(nums1, nums2) nums2.each do |num| nums1 << num end nums1.sort! median = 0 low = 0 high = nums1.length-1 mid = high/2 if high.odd? median = (nums1[mid] + nums1[mid+1]).to_f/2.to_f else median = nums1[mid].to_f end return median end ``` 偷加一個我看不懂的 ```ruby= # @param {Integer[]} nums1 # @param {Integer[]} nums2 # @return {Float} def find_median_sorted_arrays(nums1, nums2) a, b = [nums1, nums2].sort_by(&:size) m, n = a.size, b.size after = (m + n - 1) / 2 i = (0...m).bsearch { |i| after-i-1 < 0 || a[i] >= b[after-i-1] } || m nextfew = (a[i,2] + b[after-i,2]).sort (nextfew[0] + nextfew[1 - (m+n)%2]) / 2.0 end ``` ![](https://hackmd.io/_uploads/r1CccOLWp.png) ::: :::spoiler GO ```go= func findMedianSortedArrays(nums1 []int, nums2 []int) float64 { merged := append(nums1, nums2...) sort.Ints(merged) l := len(merged) if l % 2 == 0{ return float64(merged[l/2]) / 2 + float64(merged[l/2 - 1]) / 2 }else{ return float64(merged[(l-1) / 2]) } } ``` ![](https://hackmd.io/_uploads/HJd_bY8ZT.png) ::: :::spoiler Rust ```rust= impl Solution { pub fn find_median_sorted_arrays(nums1: Vec<i32>, nums2: Vec<i32>) -> f64 { let mut c_vec: Vec<i32> = [nums1, nums2].concat(); c_vec.sort(); let c_len = (c_vec.len() - 1) >> 1; (c_vec[c_len] + c_vec[c_len + (c_vec.len() - 1 & 1)]) as f64 / 2.0 } } ``` ![](https://hackmd.io/_uploads/r1G1fYIZa.png) ::: :::spoiler Typescript ```typescript= function findMedianSortedArrays(nums1: number[], nums2: number[]): number { const mn = nums1.length + nums2.length; const res = FindKthSmallList(nums1, 0, nums1.length, nums2, 0, nums2.length, Math.ceil(mn / 2)); if (mn % 2) return res; return (res + FindKthSmallList(nums1, 0, nums1.length, nums2, 0, nums2.length, (mn + 2) / 2)) / 2; } const FindKthSmallList = (A: number[], aL: number, a: number, B: number[], bL: number, b: number, K: number): number => { if (a > b) return FindKthSmallList(B, bL, b, A, aL, a, K); if (a === 0) return B[bL + K - 1]; if (K === 1) return Math.min(A[aL], B[bL]); const aK = Math.min(a, Math.ceil(K / 2)); // A+K/2 > A length const bK = K - aK; // aK+bK=K (K/2+K/2=K or a+bK=K) if (A[aL + aK - 1] < B[bL + bK - 1]) { // array index include 0 so index=length-1 return FindKthSmallList(A, aL + aK, a - aK, B, bL, b, K - aK); } else { return FindKthSmallList(A, aL, a, B, bL + bK, b - bK, K - bK); } }; ``` ![](https://hackmd.io/_uploads/Hyw0ftUbp.png) ::: :::spoiler PHP ```php= class Solution { /** * @param Integer[] $nums1 * @param Integer[] $nums2 * @return Float */ function findMedianSortedArrays($nums1, $nums2) { $sorted = []; $d1 = null; $d2 = null; while (count($nums1) > 0 || count($nums2) > 0) { $d1 = $d1 === null ? array_shift($nums1) : $d1; $d2 = $d2 === null ? array_shift($nums2) : $d2; if (($d1 !== null && $d1 <= $d2) || ($d1 !== null && $d2 === null)) { $sorted[] = $d1; $d1 = null; } elseif($d2 !== null) { $sorted[] = $d2; $d2 = null; } } if ($d1 !== null) { $sorted[] = $d1; } if ($d2 !== null) { $sorted[] = $d2; } $c = count($sorted); if ($c%2 === 0) { return ($sorted[$c/2] +$sorted[($c/2 - 1)])/2; } else { return $sorted[floor($c/2)]; } } } ``` ::: :::spoiler Swift ```swift= class Solution { func findMedianSortedArrays(_ nums1: [Int], _ nums2: [Int]) -> Double { let ln1 = nums1.count, ln2 = nums2.count var arr = Array(repeating: 0, count: ln1 + ln2), lna = arr.count var i = ln1 - 1, t = ln2 - 1, c = lna - 1 while c >= 0 { if t < 0 || i >= 0 && nums1[i] > nums2[t] { arr[c] = nums1[i] c = c - 1 i = i - 1 } else { arr[c] = nums2[t] c = c - 1 t = t - 1 } } let m = lna / 2 return lna % 2 == 0 ? Double(arr[m-1] + arr[m]) / 2 : Double(arr[m]) } } ``` ::: :::spoiler Kotlin ```kotlin= class Solution { fun findMedianSortedArrays(nums1: IntArray, nums2: IntArray): Double { val array1 = ArrayList<Int>() nums2.forEach { it -> array1.add(it) } nums1.forEach { it -> array1.add(it) } array1.sort() println(array1) val i: Double = if (array1.size % 2 == 0) { ((array1[array1.size / 2 - 1] + array1[(array1.size / 2)]).toDouble() / 2L).toDouble() } else { (array1[(array1.size / 2) ]).toDouble() } return i } } ``` ::: ::: spoiler Scala ```scala= object Solution { def findMedianSortedArrays(nums1: Array[Int], nums2: Array[Int]): Double = { val mergedArrays = (nums1 ++ nums2).sorted val isOdd = mergedArrays.length % 2 == 1 val mergedLen = mergedArrays.length if (isOdd) mergedArrays(mergedLen / 2) else (mergedArrays((mergedLen / 2) - 1) + mergedArrays(mergedLen / 2)) / 2.0 } } ``` ::: :::spoiler Dart ```dart= class Solution { double findMedianSortedArrays(List<int> nums1, List<int> nums2) { final nums = <int>[...nums1, ...nums2]..sort(); final middle = nums.length ~/ 2; //Rounded integer middle if (middle == nums.length / 2) { //Is rounded middle == real middle int x = middle; int y = middle - 1; return (nums[x] + nums[y]) / 2; } else { int x = middle; return nums[x].toDouble(); } } } ``` ::: :::spoiler Elixir ```elixir= defmodule Solution do @spec find_median_sorted_arrays(nums1 :: [integer], nums2 :: [integer]) :: float def find_median_sorted_arrays(nums1, nums2) do list = Enum.sort(nums1 ++ nums2) cond do length(list) === 1 -> Enum.at(list, 0) rem(length(list), 2) === 0 -> start_index = trunc(length(list) / 2 - 1) (Enum.at(list, start_index) + Enum.at(list, start_index + 1)) / 2 true -> start_index = div(length(list), 2) Enum.at(list, start_index) end end end ``` ::: :::spoiler Racket ```racket= (require math/flonum) (define (sorted-lists->stream list-1 list-2) (cond ((empty? list-1) list-2) ((empty? list-2) list-1) ((< (car list-1) (car list-2)) (stream-cons (car list-1) (sorted-lists->stream (cdr list-1) list-2))) (else (stream-cons (car list-2) (sorted-lists->stream list-1 (cdr list-2)))))) (define (middle-of-a-stream stream) (let loop ([scanner stream] [middle #f] [is-odd #f]) (cond ((stream-empty? scanner) (values middle is-odd)) ((not middle) (loop (stream-rest scanner) scanner (not is-odd))) ((not is-odd) (loop (stream-rest scanner) (stream-rest middle) (not is-odd))) (else (loop (stream-rest scanner) middle (not is-odd)))))) (define (average a b) (/ (+ a b) 2)) (define (stream-second stream) (stream-first (stream-rest stream))) (define/contract (find-median-sorted-arrays nums1 nums2) (-> (listof exact-integer?) (listof exact-integer?) flonum?) (let-values ([(middle is-odd) (middle-of-a-stream (sorted-lists->stream nums1 nums2))]) (fl (if is-odd (stream-first middle) (average (stream-first middle) (stream-second middle)))))) ``` ::: ---