每當成為入門CS課程(學生們學習程式設計語言的課程)的助教時,都困于提出好的練習題。 Project Euler
和類似的問題通常對初學者來說來難了,尤其是對于那些沒有很強數學背景的同學。
在這篇文章中,Adrian Neumann 收集了一些從初級到進階逐級困難的練習題,适合剛開始學習程式設計的初學者。當有新的練習題時,Adrian 會及時添加。除了一些GUI問題外,練習題一般都是算法題,無需學習任何庫就可以解決。課程練習題的困難程度有時候取決于你使用的程式設計語言。例如,關于清單List的練習題若用内部不支援List的C語言來解決的話會困難些。
即使有一定程式設計經驗的人想要學習一門新語言的時候,雖然這對他們來說相對簡單,但我認為這還是有用的。
初級
- 寫程式将” Hello World”列印到螢幕。
- 寫程式輸入使用者的姓名并用該姓名和他打招呼。
- 修改上一個程式,使得僅可以與Alice和Bob這兩個使用者用其姓名與之打招呼。
- 寫程式輸入一個數n并列印出從1到n的和。
- 修改上個程式,使得求和的數隻包含3或5的倍數,例如n=17,則求和的數為:3, 5, 6, 9, 10, 12, 15。
- 寫個程式,要求使用者輸入一個數n,并機率性的選擇是計算1到n的和還是計算1到n的乘積。
- 寫程式列印出12×12乘法表。
- 寫程式列印所有的素數。(注意:如果你用的程式設計語言不支援任意大小的數,那麼列印出所有你能表示的素數,包括最大數)
- 寫一個競猜遊戲,使用者必須猜一個秘密的數字,在每次猜完後程式會告訴使用者他猜的數是太大了還是太小了,直到猜測正确,最後列印出猜測的次數。如果使用者連續猜測同一個數字則隻算一次。
- 寫個程式列印出接下來的20個閏年。
- 寫程式計算:

清單list和字元串
- 寫一個函數,傳回清單中最大的數。
- 寫函數逆轉清單,最好是原地逆轉。
- 寫個函數檢查指定的元素是否出現在清單中。
- 寫個函數傳回清單中奇數位置的所有元素。
- 寫個函數計算清單的運作花費總和(the running total)。
- 寫個函數測試一個字元串是否是回文。
- 寫三個函數來計算清單中數字的和:分别用for循環,while循環和遞歸完成。
- 寫個函數on_all周遊清單中的每個元素,列印出開始的20個完全平方數。
- 寫個函數連接配接兩個清單。
- 寫個函數交替合并兩個清單,例如:[a,b,c], [1,2,3] → [a,1,b,2,c,3]。
- 寫個函數合并兩個有序的清單。
- 寫個函數計算前100個Fibonacci數的清單。
- 寫個函數,傳回指定數的各位數字的清單。
- 寫個函數對兩個數進行加減乘,使用各個位上的數字表示的清單實作并傳回一個新的數字清單,如果你有信心可以實作Karatsuba乘法。 嘗試不同的基數 ,如果你關心速度可以比較下哪個是最佳基數。
- 實作下面的排序算法:選擇排序,插入排序,歸并排序,快速排序, 臭皮匠排序 (Stooge Sort)。具體的描述見Wikipedia。
- 實作二分查找。
- 寫個函數,給定一個字元串清單并按下面表示列印出來,一行一個列印在矩形框中。例如清單["Hello", "World", "in", "a", "frame"] 列印的結果是:
*********
* Hello *
* World *
* in *
* a *
* frame *
- 寫函數将一段文本text翻譯為Pig Latin傳回,英語翻譯為Pig Latin的規則是:取出每個單詞的首個字母,追加’ay’後再放到該單詞的末尾。例如“The quick brown fox” 翻譯後就變成了 “Hetay uickqay rownbay oxfay”。
中級
1.寫程式在1,2,…,9(保持這個順序)之間可任意放+或-或都不放使其結果等于100,輸出所有可能的放法。例如:1 + 2 + 3 – 4 + 5 + 6 + 78 + 9 = 100。
2.寫程式以一個假想行星的一年持續時間作為輸入,産生一個閏年規則,最大限度的減少與該行星的太陽年的差異。
3.實作資料結構圖,允許修改(插入,删除),并能夠存儲邊和節點的值。可能使用(node, edgelist)字典對表示完成該功能最容易。
4.寫個函數生成圖的DOT表示(譯者注:
DOT語言是一種文本圖形描述語言,它提供了一種簡單的描述圖形的方法,并且可以為人類和計算機程式所了解。)。
5.寫程式自動的給你生成文章:
(1)使用一個樣例文本sample建立有向(多)圖,其中文本單詞作為節點,如果文本中u後面是v則u和v之間有一條有向邊,多次出現生成多條邊。
(2)在該圖中做随機周遊:從一個随機的節點開始選擇一個随機的後繼節點,如果沒有後繼節點就随機的選擇另一個節點。
6.寫程式自動的将英文文本轉換為摩爾斯電碼(譯者注: 摩斯碼(
Morse Code)是一種時通時斷的信号代碼,通過不同的排列順序來表達不同的英文字母、數字和标點符号)或者相反。
7.寫程式找出給定字元串的最長回文子串,盡可能高效的實作。
進階
- 給定兩個字元串,寫程式高效的找出最長的公共子串。
- 給定一個整數數組,寫程式高效的查詢:比位置i處的數稍大的最近鄰數,這裡的距離是指數組下标的絕對差。例如數組[1,4,3,2,5,7],比4大的最近的數是5。先用線性時間做預處理,然後用常數時間做查詢。
- 給定兩個字元串,使用字元插入和删除将其中的一個字元串轉變成另一個,輸出最短的插入和删除序列。
- 寫個函數實作兩個矩陣相乘。盡可能高效的實作并使用較好的線性代數庫(linear algebra library,具體可看 這裡 )進行性能比較。你也許想讀一下 Strassen’s algorithm 和CPU緩存的影響,嘗試不同的矩陣布局,看看發生了什麼。
- 給定d維矩陣框集合,寫程式計算它們交集的體積,從2維開始逐漸計算。
GUI
- 寫一個展示彈跳球的程式。
- 寫一個記憶體遊戲。
- 寫一個俄羅斯方塊工程Tetris clone。
最後的開放性問題
寫一個盡可能好玩的猜字遊戲Hangman。例如你可以
使用這樣的大字典并選擇排除大部分單詞仍有解決方案的字母。盡可能高效的實作,比如不要每一輪都掃描整個詞典。
寫個程式與人類玩石頭剪刀布(Rock, Paper, Scissors),嘗試證明人類非常不善于生成随機數字。
寫個程式與人類對手玩Battle Ship(海戰棋,是雙人玩的猜謎遊戲),輸入坐标并輸出是否擊中及此次射擊的坐标。
--
其它收集
當然我不是第一個提出要收集類似上面清單這種思想的人。
*
John Dalbey的收集
* 幾個小問題
程式設計實踐* CPE 101
項目 Code Kata 99 Lisp Problems,
99 Haskell Problems. 這裡的大部分問題都可以用其它語言解決。
Rosetta Code Programming Tasks. 這些問題提供了多語言解決方法!
Code Golf Challenges. 這裡的目标是用盡可能少的字元解決問題。
SPOJ Problems. 這是一個超過13000個問題的清單!