Go 入門層級實戰
看了一段時間的 Go 基礎文法,總覺得缺了點什麼,所以今天就想試試寫點什麼
附.目錄結構
binary.go
、 cache.go
、 fibonacci.go
都屬於 chestnut_math 包
main.exe
為構建後的可執行檔
main.go
為 main 包 主入口檔案
test.go
一個單獨的 main 包 測試用(獨立)
一. 斐波那契數列
原理其實很簡單,就是一個遞迴...
1.求值代碼
這是 fibonacci.go
檔案代碼
package chestnut_math// 擷取斐波那契數列指定位對應值func GetFibonacci(int_num uint64) uint64 { if int_num < 3 { return 1 } else { return GetFibonacci(int_num - 2) + GetFibonacci(int_num - 1) } }
2.緩衝
為什麼寫個緩衝方法呢?因為是位元越大耗時越長,但畢竟值是不變的,所以不需要每次都重新算一遍
cache.go
檔案
package chestnut_math// 斐波那契集合var map_fibonacci = make(map[string]string)// 緩衝斐波那契func CacheFibonacci(key string, value string) { _, validate := map_fibonacci[key] if !validate { map_fibonacci[key] = value }}// 擷取緩衝func GetCache(key string) string { value, validate := map_fibonacci[key] if validate { return value } else { return "" }}
二.十進位轉二進位
binary.go
檔案
// 十進位轉二進位func Dtob (read_line []byte) string { read_line_string := string(read_line) int_current, error := strconv.Atoi(read_line_string) if error != nil { fmt.Println(error)} var string_binary string for true { if int_current < 1 { return string_binary } string_binary = strconv.Itoa( int_current % 2 ) + string_binary int_current /= 2 } return "0"}
三.二進位轉十進位
binary.go
檔案
// 二進位轉十進位func Btod(read_line []byte) int { var value_sum, value_square int for index, value := range read_line { value_int, error := strconv.Atoi(string(value)) if error != nil { fmt.Println(error) } index_new := len(read_line) - 1 - index if index_new == 0 { value_square = 1 } else { value_square = 2 << uint(index_new - 1)} value_sum += value_int * value_square } return value_sum}
四.main包
seaconch 在實踐中遇到一個問題,那就是在迴圈
(也包括goto
)中使用 fmt.Scanf
接收輸入時總是會出現跳過一次輸入的問題
通過查詢資料得出結論可能和 fmt.Scanf
讀取斷行符號鍵有關係
沒有找到什麼好的解決方案,最好只好將擷取輸入的方式全部改成了 reader.ReadLine()
的方式
相應的之後的一些類型轉換也做的不是很好,不過應該會找到更好的解決方案的
main.go
檔案
package mainimport ( "strconv" "os" "bufio" "fmt" "./chestnut_math")func main() { fmt.Println(" 歡迎使用 Go 進位轉換小助手 v 0.1 ") reader := bufio.NewReader(os.Stdin) for true { fmt.Println("+——————————————————") fmt.Println("| 輸入 1 進行斐波那契數列求值計算") fmt.Println("| 輸入 2 進行十進位轉換二進位計算") fmt.Println("| 輸入 3 進行二進位轉換十進位計算") fmt.Println("+——————————————————") read_line_select, _, _ := reader.ReadLine() read_line_select_string := string(read_line_select) switch read_line_select_string { case "1" : fibonacci(reader) case "2" : bdConvert(reader, 2) case "3" : bdConvert(reader, 3) } fmt.Print("輸入 y 繼續,其他則退出\t") read_line_answer, _, _ := reader.ReadLine() if read_line_answer_string := string(read_line_answer); read_line_answer_string == "y" { fmt.Println() continue } else { break } }}// 斐波那契數列func fibonacci(reader *bufio.Reader) { fmt.Println("請問想擷取斐波那契數列的第幾位?") read_line, _, _ := reader.ReadLine() read_line_string := string(read_line) read_line_int, error := strconv.Atoi(read_line_string) if error != nil {fmt.Println("發生錯誤:", error)} fmt.Println("拼啦命的計算中...") string_temp := chestnut_math.GetCache(read_line_string) if string_temp != "" { fmt.Printf("第 [%d] 位斐波那契數為 : %s\n", read_line_int, string_temp) fmt.Print("資料來自緩衝") return } int_result := chestnut_math.GetFibonacci(uint64(read_line_int)) cache_value := strconv.FormatUint(int_result, 10) chestnut_math.CacheFibonacci(read_line_string, cache_value) fmt.Printf("第 [%d] 位斐波那契數為 : %d\n", read_line_int, int_result)}// 進位轉換func bdConvert(reader *bufio.Reader, int_type int) { if int_type == 2 { fmt.Println("請輸入十進位自然數") } else { fmt.Println("請輸入二進位自然數") } read_line, _, _ := reader.ReadLine() if int_type == 2 { string_result := chestnut_math.Dtob(read_line) fmt.Println(string_result) } else { int_result := chestnut_math.Btod(read_line) fmt.Println(int_result) }}
五.