# 2024年 「[資訊科技產業專案設計](https://hackmd.io/@sysprog/info2024/https%3A%2F%2Fhackmd.io%2F%40sysprog%2Finfo2024-homework2)」課程第二次作業 ## 模擬面試檢討 [魯智深-NatureLover - 他評01](https://hackmd.io/Fa1bSAKeR6G2Eq3p8m52pA?view#%E4%BB%96%E8%A9%9501) [伊娃咳夫-Ivancough - 他評04](https://hackmd.io/@sysprog/HybZJ8WJ1x#%E4%BB%96%E8%A9%95-04) [歐麥-Allmine - 他評01](https://hackmd.io/8_RectOKTM6qdrMAhZfc3Q?view#%E4%BB%96%E8%A9%9501) [吸嘉佳-Newo - 他評01](https://hackmd.io/0tTzkgf0Qn6zK2mY-RUNCw?view#%E4%BB%96%E8%A9%9501) [黎特寇-Mark - 同儕檢討02](https://hackmd.io/9aagcOrsT4GjAZbYSkD5Ig?view#%E5%90%8C%E5%84%95%E6%AA%A2%E8%A8%8E02) # info2024-homework2 > 歐麥-Allmine > 哈哈球-Hahaball > R : Interviewer, E : Interviewee > [Interviewer](https://www.youtube.com/watch?v=8zD7ZNKfKKo) > [interviewee](https://youtu.be/EohokVYF_Ug) ## 20. Valid Parentheses() R : 您好,我是哈哈球,我們最近有一個改進內部IDE的需求,當開發人員在寫扣時,經常會出現括號不匹配的問題,這不僅可能導致執行錯誤,也會增加代碼調試的負擔。為了改善這一點,我們希望在內部的 IDE 中添加一個即時的括號匹配檢查功能。這個功能要能即時檢查各類括號(如 `()`, `{}`, `[]`)的匹配情況,並在發現不匹配的括號時立刻顯示提示,以協助同仁迅速找到並修正錯誤。 ### (Repeat) E : 所以您的問題是, 我需要實作一個功能, 檢查IDE裡的括號是否有各自正確匹配? R : 對的 ### (Example) E : 兩個左括號`([`, 如果對應到兩個右括號`])`就可以回傳`True` 但如果括號大小不匹配, 例如`{(})`,或是數量不匹配`{}}}}`,則都要回傳`False` R : 對的,僅需考慮括號數量匹配與否, 不用考慮大小括號優先順序問題 ### (Approach) E : 好, 我先寫下方法, 我想用`stack[]`LIFO的特性, 來記錄括號的順序, 遇到左括號就push進`stack`, 遇到右括號則pop, 但要與`stack`最上方的左括號匹配,以及top不能為`-1`,否則就回傳`false` 最後回傳`top==-1` #### psuedo code ``` top = -1 stack[top] 1. *s = '(', stack[++top] = *s; 2. *s = ')', if(top>-1且stack[top]=='(') 跳出switch-case, 否則return false 最後return top==-1. ``` R : 恩,你的做法聽起來沒有太大的問題 ### (code) ```c== bool isValid(char* s) { int len = strlen(s); char stack[len]; int top = -1; while(*s!='\0') { switch(*s) { case ')': if(top>-1 && stack[top--]=='(') break; else return false; case ']': if(top>-1 && stack[top--]=='[') break; else return false; case '}': if(top>-1 && stack[top--]=='{') break; else return false; default : stack[++top] = *s; break; } s++; } return top==-1; } ``` #### 時間複雜度:O(N), 空間複雜度:O(N) R: 那可以請你用`()[]`解釋一下程式如何運行嗎? ### (Test:) ( )[ ] E : 跑測資 R: 在switch-case的部分, 針對左括號的操作邏輯看起來一樣的, 那可以請你用if-else將左括號的操作統一處理嗎? ### (Optimization) ```c== bool isValid(char* s) { int len = strlen(s); char stack[len]; int top = -1; while(*s!='\0') { if(*s=='('||*s=='['||*s=='{') { stack[++top] = *s; } else { if(top==-1 || \ (*s==')' && stack[top]!='(') || \ (*s==']' && stack[top]!='[') || \ (*s=='}' && stack[top]!='{')){ return false; } top--; } s++; } return top==-1; } ``` #### 時間複雜度:O(N), 空間複雜度:O(N) R: 恩, if-else的部分也沒有甚麼問題, 感謝您今天的寶貴時間。 ## 9. Palindrome Number R: 你好,我們公司最近在對文本處理和自然語言處理(NLP)中需要做更精確的識別和分類,而其中一項關鍵技術為回文(Palindrome)的檢查,它可以幫助識別一些特定語義或文本的特徵,並應用於判別抄襲或重複內容,甚至是垃圾郵件的檢測。為了簡化測試,為了簡化測試,我們將以整數作為文本內容,請你寫出一個能達到上述效果的函式。 ### (Repeat) E: 所以在這個問題我會先拿到一個整數,那這個整數有可能是正數或是負數吧?而我需要做的事情就是去檢查他是否為一 Palindrome ? R: 沒錯。 ### (Example) E: 舉例來說,假使我今天拿到的數字是 -595 ,那就要回傳 `False` ,而如果是 595 就要回傳 `True` ? R: 是的。 E: 那我的想法會是先去判斷輸入的數是否為正數,如果不是直接 return `False` ,是的話再去做回文的判斷。而判斷的方式為從 `x` 的個位數開始往高位移動,並記錄每一次的值,使得最終得到一個與 `x` 完全相反的數,最後再去判斷兩數是否相等即可。 ### (Code) ```c== bool isPalindrome(int x) { if(x < 0) return 0; int temp = x; int rev = 0; while(temp > 0){ rev = rev*10+temp%10; temp /= 10; } return rev == x; } ``` R: 看起來是可行的,但如果輸入的整數位數比較多,那就會造成 overflow 的情況,你的程式碼有辦法改進嗎? E: 那如果是考量到 overflow 的情形,主要發生的地方會在程式碼中 `rev = rev*10` 的操作,因此我會選擇將 `rev` 的型態從 `int` 改為 `long long` ,如此一來便能使用 64 個位元去儲存。 ```c== int rev; -> long long rev; ``` ### (Test) : 464 R: 你使用了 long long 讓 `rev` 從 32 轉為 64 bits ,這的確可以讓它擁有更大的數值範圍,那如果我希望不使用 `long long` 呢? E: 如果不希望使用 `long long` 且又要避免 overflow 的情況發生的話,那我會選擇用陣列來解決這個問題。首先,將 `x` 的每一位數儲存至陣列裡,然後直接對陣列中相對應的位置判斷是否相等即可,例如有一個大小為 4 的陣列,若他是回文,則 index 0 和 3 的值以及 index 1 和 2 的值必須相等,若有不相等的情況發生則不用繼續比較,直接回傳 `False` 就可以了。 ```c== bool isPalindrome(int x) { if(x < 0) return 0; int temp = x; int count = 0; while(temp){ temp /= 10; count++; } int* arr = (int*)malloc(count*sizeof(int)); for(int i = 0; i < count; i++){ arr[i] = x%10; x /= 10; } for(int j = 0; j < count/2; j++){ if(arr[j] != arr[count-1-j]) return 0; } free(arr); return 1; } ``` R: 謝謝你今天的參與。