51

Go 入门实战

 5 years ago
source link: https://studygolang.com/articles/13512?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Go 入门级别实战

看了一段时间的 Go 基础语法,总觉得缺了点什么,所以今天就想试试写点什么

附.目录结构

1460000015567341?w=219&h=181

binary.gocache.gofibonacci.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 main

import (
    "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)
    }

}

五.效果图

1460000015567342?w=781&h=792


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK