golang经典编程题30题(带答案)golang基础算法30题

1.打印出九九乘法表并统计耗时

package main

import (
	"fmt"
	"time"
)

func main() {
	start := time.Now()
	var i, j int
	for i = 1; i <= 9; i++ {
		for j = 1; j <= i; j++ {
			fmt.Printf("%d*%d=%d\t", i, j, i*j)
		}
		fmt.Println()
	}
	tc := time.Since(start)
	fmt.Printf("耗时是%v", tc)
}

2.求两个数的求最大公约数和最小公倍数。

package main

import "fmt"

func getMaximumCommonDivisor(a, b int) int {
	//获取最大公约数

	for a != b {
		if a > b {
			a = a - b
		} else if a < b {
			b = b - a
		}
	}

	return a

}
func main() {
	var a, b = 24, 10
	num := getMaximumCommonDivisor(a, b)
	fmt.Println("a,b的最大公约数是:", num)
	//求最小公倍数相对来说就比较简单了。只需要先求出最大公约数。用两个数的乘积除以最大公约数即可
	fmt.Println("a,b的最小公倍数是:", a*b/num)
}
//结果:
//a,b的最大公约数是: 2
//a,b的最小公倍数是: 120


3.回文数的判断
回文数的概念:即是给定一个数,这个数顺读和逆读都是一样的。例如:121,1221是回文数,123,1231不是回文数。


package main

import (
	"fmt"
)

func isHuiwen(a string) bool {
	var i, j int
	var b bool
	for i = 0; i <= len(a)/2-1; i++ {
		j = len(a) - 1
		if a[i] != a[j] {
			b = false
		}
		b = true
		j--
	}
	return b
}
func main() {
	a := "1002332001"
	isHuiwen(a)
	fmt.Println(isHuiwen(a))
}

4.求水仙花数
水仙花数是指一个 3 位数,它的每个位上的数字的 3次幂之和等于它本身(例如:1^3 + 5^3+ 3^3 = 153)

package main

import (
	"fmt"
)

func isNarcissisticNum(num int) bool {
	a := num / 100       //分离出百位a
	b := (num / 10) % 10 //分离处十位b
	c := num % 10        //分离出个位c
	result := a*a*a + b*b*b + c*c*c
	if num == result {
		return true
	}
	return false
}
func main() {
	for i := 100; i < 1000; i++ {
		if isNarcissisticNum(i) {
			fmt.Println("水仙花数有:", i)
		}
	}
}
//结果:
//水仙花数有: 153
//水仙花数有: 370
//水仙花数有: 371
//水仙花数有: 407

5.求1-10000之间的同构数
正整数n若是它平方数的尾部,则称n为同构数。
例如:5的平方数是25,且5出现在25的右侧,那么5就是一个同构数。

package main

import "fmt"

func main() {
	var i, j, k int
	k = 10
	for i = 1; i <= 10000; i++ {
		if i == k {
			k *= 10
		}
		j = i * i
		if j%k == i {
			fmt.Printf("%d是同构数, %d的平方是%d\n", i, i, j)
		}
	}
}

//结果:
//1是同构数, 1的平方是1
//5是同构数, 5的平方是25
//6是同构数, 6的平方是36
//25是同构数, 25的平方是625
//76是同构数, 76的平方是5776
//376是同构数, 376的平方是141376
//625是同构数, 625的平方是390625
//9376是同构数, 9376的平方是87909376

6.编写一个函数,求100以内的质数
质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数

package main

import (
	"fmt"
	"math"
)

func isPrime(i int) bool {
	for j := 2; float64(j) <= math.Sqrt(float64(i)); j++ {
		if i%j == 0 {
			return false

		}
	}
	return true
}
func main() {
	var str []int//存放质数
	j := 0
	for i := 2; i < 100; i++ {
		if isPrime(i) {
			str = append(str, i)
			j++
		}
	}
	fmt.Println(str)
}
//结果
//[2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97]

7.分析以下需求,并用代码实现:
(1)根据工龄(整数)给员工涨工资(整数),工龄和基本工资通过键盘录入
(2)涨工资的条件如下:
[10-15) +5000
[5-10) +2500
[3~5) +1000
[1~3) +500
[0~1) +200
(3)如果用户输入的工龄为10,基本工资为3000,程序运行后打印格式"您目前工作了10年,基本工资为 3000元,
应涨工资 5000元,涨后工资 8000元"


package main

import "fmt"

func main() {
	var n, salary, sum, a int
	var err error

	fmt.Println("请输入您的工龄")
	_, err = fmt.Scanln(&n)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("请输入您的基本工资")
	_, err = fmt.Scanln(&salary)
	if err != nil {
		fmt.Println(err)
	}
	if n >= 0 && n < 1 {
		a = 200
	} else if n >= 1 && n < 3 {
		a = 500
	} else if n >= 3 && n < 5 {
		a = 1000
	} else if n >= 5 && n < 10 {
		a = 2500
	} else if n >= 10 && n < 15 {
		a = 5000
	}
	sum = salary + a
	fmt.Printf("您目前工作了%d年,基本工资为%d元,应涨工资%d元,涨后工资%d元", n, salary, a, sum)
}

8.(1)定义一个map存下面数据
France 首都是 巴黎
Italy 首都是 罗马
Japan 首都是 东京
India 首都是 新德里
(2)检测American 的首都是否存在
(3)将map的数据存入到mysql数据库


package main

import (
	"database/sql"
	"fmt"

	_ "github.com/go-sql-driver/mysql" //注册MySQL驱动
)

func main() {
	//创建集合
	var countryCapitalMap map[string]string
	countryCapitalMap = make(map[string]string)

	// map插入key - value对,各个国家对应的首都
	countryCapitalMap["France"] = "巴黎"
	countryCapitalMap["Italy"] = "罗马"
	countryCapitalMap["Japan"] = "东京"
	countryCapitalMap["India "] = "新德里"

	//使用键输出地图值
	for country := range countryCapitalMap {
		fmt.Println(country, "首都是", countryCapitalMap[country])
	}

	//查看元素在集合中是否存在
	capital, ok := countryCapitalMap["American"] //如果确定是真实的,则存在,否则不存在

	if ok {
		fmt.Println("American 的首都是", capital)
	} else {
		fmt.Println("American 的首都不存在")
	}
	//用户名:密码@tcp(地址:3306)/数据库名
	db, err := sql.Open("mysql", "root:123456@tcp(192.168.2.132:3306)/test")
	if err != nil {
		fmt.Println(err)
	}
	//往数据库插入数据
	for k, v := range countryCapitalMap {
		result, err := db.Exec("INSERT INTO countryCapital(country,capital)VALUES (?,?)", k, v)
		if err != nil {
			fmt.Println(result, err)
		}
	}

}

9.判断两个map是否拥有相同的键和值

//判断两个map是否拥有相同的健和值
package main

import (
	"fmt"
	_ "fmt"
)

func equal(x, y map[string]int) bool {
	if len(x) != len(y) {
		return false
	}
	for k, xValue := range x {//使用!ok来区分元素不存在和元素存在但值为0的情况
		if yValue, ok := y[k]; !ok || yValue != xValue {
			return false
		}

	}
	return true
}
func main() {
	x := map[string]int{
		"A": 0,
		"B": 1,
		"C": 2,
		"D": 3,
	}
	y := map[string]int{
		"B": 1,
		"C": 2,
		"D": 3,
	}
	z := map[string]int{
		"A": 0,
		"B": 1,
		"C": 2,
		"D": 3,
	}
	fmt.Println(equal(x, y))
	fmt.Println(equal(x, z))
}

10.编写一个函数实现顺序遍历map中的元素

//写一个函数实现顺序遍历map中的元素
package main

import (
	"fmt"
	_ "fmt"
	"sort"
	_ "sort"
)

func sortMap(student map[string]int) {
	var names []string
	for name := range student {
		names = append(names, name)
	}
	sort.Strings(names)
	for _, name := range names {
		fmt.Printf("%s的年龄是%d\n", name, student[name])
	}
}
func main() {
	student := map[string]int{
		"lisa":     17,
		"bob":      20,
		"victoria": 24,
		"sabit":    40,
	}
	sortMap(student)
}

11.定义一个map,存1到20的阶乘并顺序输出
方法一:

package main

import (
	"fmt"
)

func main() {
	m := make(map[int]int)
	for i := 0; i <= 20; i++ {
		if i == 0 {
			m[i] = 1
		} else {
			m[i] = m[i-1] * i

		}
		fmt.Println(i, "的阶乘是", m[i])
	}

}

方法二:(阶乘计算完再顺序输出)

package main

import (
	"fmt"
	"sort"
)
func main() {
	m := make(map[int]int)
	for i := 0; i <= 20; i++ {
		if i == 0 {
			m[i] = 1
		} else {
			m[i] = m[i-1] * i

		}

	}
	arr := make([]int, 0)
	for k, _ := range m {
		arr = append(arr, k)

	}
	sort.Ints(arr)
	for i := 0; i <= len(arr)-1; i++ {
		fmt.Println(arr[i], "的阶乘是", m[arr[i]])
	}

}

12.约瑟夫环问题
编号为 1-N 的 N 个士兵围坐在一起形成一个圆圈,从编号为 1 的士兵开始依次报数(1,2,3…这样依次报),数到 k 的 士兵会被杀掉出列,之后的士兵再从 1 开始报数。直到最后剩下一士兵,求这个士兵的编号。

//n个人,每数到k就出圈
package main

import "fmt"

func josephus(n int, k int) int {
	if n == 1 {
		return n
	}
	return (josephus(n-1, k)+k-1)%n + 1

}

func main() {
	n := 5
	k := 2
	res := josephus(n, k)
	fmt.Println(res)
}
//结果3

13.给出一串字符,要求统计出里面的字母、数字、空格以及其他字符的个数。

package main

import "fmt"

func countUnicode(s string) {
	var letter int //字母个数
	var num int    //数字个数
	var space int  //空格个数
	var other int  //其他个数
	for i := 0; i < len(s); i++ {
		if (s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z') {
			letter++
		} else if s[i] >= '0' && s[i] <= '9' {
			num++
		} else if s[i] == ' ' {
			space++
		} else {
			other++
		}
	}
	fmt.Printf("字母的个数为%d\n", letter)
	fmt.Printf("数字的个数为%d\n", num)
	fmt.Printf("空格的个数为%d\n", space)
	fmt.Printf("其他字符的个数为%d\n", other)
}
func main() {
	s := "A, B, 44...,5 Z、a, b, ..., &&z  "
	countUnicode(s)
}
//结果:
//字母的个数为6
//数字的个数为3
//空格的个数为8
//其他字符的个数为17

14.编写一个函数就地反转一个整型slice中的元素

//就地反转一个整型slice中的元素
package main

import "fmt"

func reverse(s []int) []int {
	for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
		s[i], s[j] = s[j], s[i]
	}
	return s
}
func main() {
	var s []int = []int{1, 2, 3, 4, 5, 6, 7}
	fmt.Println(reverse(s))
}

15.判断两个slice是否拥有相同的元素

package main

import "fmt"

func equal(x, y []string) bool {
	if len(x) != len(y) {
		return false
	}
	for i := range x {
		if x[i] != y[i] {
			return false
		}
	}
	return true
}
func main() {
	x := []string{"a", "b", "c", "d"}
	y := []string{"a", "d", "p", "d"}
	z := []string{"a", "b", "c", "d"}
	fmt.Println(equal(x, z))
	fmt.Println(equal(y, z))
}
//结果:
//true
//false


16.翻转二维数组
翻转下面这个二维数组
a = [][]nt{
{0, 1, 2, 3} ,
{4, 5, 6, 7} ,
{8, 9, 10, 11},
}


package main

import "fmt"

func transpose(a [][]int) [][]int {
	//只有一行则不是二维数组
	if len(a[0]) == 0 {
		return nil
	}
	row := len(a[0]) //arr的row
	col := len(a)    //arr的col
	arr := make([][]int, row, row)
	for i := 0; i <= row-1; i++ {
		arr[i] = make([]int, col)
	}
	for k := col - 1; k >= 0; k-- {
		for y := row - 1; y >= 0; y-- {
			arr[y][k] = a[k][y]

		}

	}

	fmt.Println(arr)
	return arr
}
func main() {
	a := [][]int{
		{0, 1, 2, 3},
		{4, 5, 6, 7},
		{8, 9, 10, 11},
	}
	transpose(a)

}

17.斐波那契数列
斐波那契数列指的是这样一个数列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55…
这个数列从第3项开始,每一项都等于前两项之和


package main

import "fmt"

func isFibonacciSequence(i int) int {
	if i <= 1 {
		return 1
	}
	return isFibonacciSequence(i-1) + isFibonacciSequence(i-2)
}
func main() {
	var i int = 10
	var j int = 3
	fmt.Println("第", i+1, "项的值为", isFibonacciSequence(i))
	fmt.Println("第", j+1, "项的值为", isFibonacciSequence(j))
}

18.猴子吃桃子
猴子第一天摘了若干个桃子,当即吃了一半,还不解馋,又多吃了一个;第二天,吃剩下的桃子的一半,还不过瘾,又多吃了一个;以后每天都吃前一天剩下的一半多一个,到第10天想再吃时,只剩下一个桃子了。问第一天共摘了多少个桃子?

package main

import "fmt"

func f(n int) int {
	if n == 1 {
		return 1 //最后一天只有一个桃子
	} else {
		return 2*f(n-1) + 2
	}
}

func main() {
	sum := (f(10))//十天前有sum个桃子
	fmt.Printf("第一天摘了%d个桃子", sum)
}
//结果:
//第一天摘了1534个桃子


19、出售金鱼
卖家将养的一缸金鱼分五次出售,第一次出售上一次卖出全部的一半加二分之一条;第二次卖出余下的三分之一加三分之一条;第三次卖出余下的四分之一加四分之一条;第四次卖出余下的五分之一加五分之一条;最后卖出余下的11条。问原来的鱼缸中共有几条金鱼?

package main

import "fmt"

func main() {
	res := 11
	for j := 4; j >= 1; j-- {
		res = (res*(j+1) + 1) / j
	}
	fmt.Println("原来的鱼缸中共有", res, "条鱼")
}
//结果:
//原来的鱼缸中共有 59 条鱼


20.无重复字符的最长子串
题目的意思是,给我们一个字符串,让我们求最长的无重复字符的子串,注意这里是子串,不是子序列,所以必须是连续的。

package main

import "fmt"

func lengthOfLongestSubstring(s string) int {
	var left, res int
	usedChar := make(map[rune]int)
	for i, v := range s {
		if k, ok := usedChar[v]; ok && left <= k {
			left = k + 1
		} else {
			res = max(res, i-left+1)
		}

		usedChar[v] = i
	}
	return res
}

func max(a, b int) int {
	if a > b {
		return a
	} else {
		return b
	}
}

func main() {
	var t string = "3456789x1234123"
	var m string = "sdkjfisf56789x1234123"
	fmt.Println(lengthOfLongestSubstring(t))
	fmt.Println(lengthOfLongestSubstring(m))
}

详细解析可以参考链接(https://blog.csdn.net/cbmljs/article/details/88973088)
21.在一个无序不重复数组中,求两个元素相加值为100的有多少对

【问题描述】
给定一个数组,求两个数之和=给定值sum的所有组合个数。
【方法一】穷举法
从数组中任意找两个数,看其和是否=sum。时间复杂度O(N^2)

【方法二】hash表法
只需要遍历一遍数组,非常高效
思路:定义一个map,一开始为空,不存数据,开始遍历数组,判断第一个元素是否有另一半已经在map中,如果有count++,没有的话,把第一个元素存入map;继续遍历第二个元素,判断第二个元素是否有另一半已经在map中,如果有count++,没有的话,把第二个元素存入map…遍历结束,结果也出来了
代码:

package main

import (
	"fmt"
)

func getSumNum(arr []int, sum int) int {
	tp := make(map[int]int)//map存数组里的元素,注意,这里map初始为空
	var count int//计个数

	for i := 0; i <= len(arr)-1; i++ {//遍历数组
	//判断这个元素的“另一半”是否已经在map里
		if _, ok := tp[sum-arr[i]]; ok {//如果在,就说明数组中有这个元素的“另一半”
			count++
		} else {//如果不在,就把这个元素加入map中
			tp[arr[i]] = i
		}

	}
	return count
}

func main() {
	var brr []int = []int{1, 12, 14, 40, 56, 60, 88, 78, 99}
	var sum int = 100
	fmt.Println(getSumNum(brr, sum))
}

22.使用golang实现词频统计。步骤:
(1)从文件中读取一篇文章。
(2)统计词频,按单词出现的频率从大到小进行排序
(3)写入到文件中。

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"sort"
	"strings"
	"unicode"
)

func getWordFrequency(readFilePath string, writeFilePath string) {
	var fileText string
	var wordFrequencyMap = make(map[string]int)
	//读取文件
	fileData, err := ioutil.ReadFile(readFilePath)
	if err != nil {
		log.Fatal(err)
	}

	fileText = string(fileData)
	//去掉分隔符
	f := func(c rune) bool {
		if !unicode.IsLetter(c) && !unicode.IsNumber(c) {
			return true
		}
		return false
	}
	arr := strings.FieldsFunc(fileText, f)
	//如果字典里有该单词则加1,否则添加入字典赋值为1
	for _, v := range arr {
		if _, ok := wordFrequencyMap[v]; ok {
			wordFrequencyMap[v] = wordFrequencyMap[v] + 1
		} else {
			wordFrequencyMap[v] = 1
		}
	}
	//fmt.Println(wordFrequencyMap)
	//按照单词出现的频率排序
	type wordFrequencyNum struct {
		Word string 
		Num  int    
	}
	var lstWordFrequencyNum []wordFrequencyNum
	for k, v := range wordFrequencyMap {
		lstWordFrequencyNum = append(lstWordFrequencyNum, wordFrequencyNum{k, v})
	}
	sort.Slice(lstWordFrequencyNum, func(i, j int) bool {
		return lstWordFrequencyNum[i].Num > lstWordFrequencyNum[j].Num
	})
	fmt.Println("按照单词出现频率由高到低排序", lstWordFrequencyNum)
	//写入文件
	var jsonBytes []byte
	var arrJsonBytes string
	for _, v := range lstWordFrequencyNum {
		jsonBytes, err = json.Marshal(v)
		if err != nil {
			log.Fatal(err)
		}
        arrJsonBytes = arrJsonBytes + string(jsonBytes)
	}
	err = ioutil.WriteFile(writeFilePath, []byte(arrJsonBytes), os.ModePerm)
	if err != nil {
		log.Fatal(err)
	}

}
func main() {
	readFilePath := "C:\\Users\\zyq\\go\\src\\yj\\artical.txt"//读取的文件路径
	writeFilePath := "C:\\Users\\zyq\\go\\src\\yj\\wordFrequency.txt"//写入的文件路径
	getWordFrequency(readFilePath, writeFilePath)
}

写入文件部分也可替换成

//写入文件
	var arrJsonBytes string
	arrJsonBytes = arrJsonBytes + "[" + "\r\n"
	for k, v := range lstWordFrequencyNum {

		arrJsonBytes = arrJsonBytes + "{" + "\"" + v.Word + "\"" + ":" + strconv.Itoa(v.Num) + "}"
		if k != len(lstWordFrequencyNum)-1 {
			arrJsonBytes = arrJsonBytes + "," + "\r\n"
		}

	}
	arrJsonBytes = arrJsonBytes + "\r\n" + "]"
	err = ioutil.WriteFile(writeFilePath, []byte(arrJsonBytes), os.ModePerm)
	if err != nil {
		log.Fatal(err)
	}

23.golang 实现单链表(增删改查)

package main

import (
	"fmt"
)

type studentNode struct {
	no   int
	name string
	age  int
	next *studentNode
}

//给链表插入一个结点
//编写第一种插入方法,在单链表的最后加入
func insertStudentNode(head *studentNode, newStudentNode *studentNode) {
	//思路:
	//1.先找到该链表的最后这个结点
	//2.创建一个辅助结点
	temp := head
	for {
		if temp.next == nil { //表示找到最后
			break
		}
		temp = temp.next //让temp不断的指向下一个结点
	}
	//3.将newStudentNode加入到链表的最后
	temp.next = newStudentNode
}

//第二种插入方法,根据no的编号从大到小插入
func sortInsertStudentNode(head *studentNode, newStudentNode *studentNode) {
	//思路
	//1.找到适当的位置
	//2.创建一个辅助结点
	temp := head
	flag := true
	//把newStudentNode.no和temp.next.no作比较
	for {
		if temp.next == nil { //说明已经到链表的最后啦
			break
		} else if temp.next.no > newStudentNode.no {
			//说明newStudentNode就应该插入到temp的后面
			break
		} else if temp.next.no == newStudentNode.no {
			//说明链表中已经有这个no了
			flag = false
			break
		}
		temp = temp.next
	}
	if !flag {
		fmt.Println("已经存在no=", newStudentNode)
	} else {
		newStudentNode.next = temp.next
		temp.next = newStudentNode
	}
}

//删除一个结点
func delStudentNode(head *studentNode, id int) {
	temp := head
	flag := false
	//找到要删除的结点的no,和temp的下一个结点的no比较
	for {
		if temp.next == nil { //说明已经到链表的最后了
			break
		} else if temp.next.no == id {
			//说明我们找到这个要删除的结点了
			flag = true
			break
		}
		temp = temp.next
	}
	if flag {
		temp.next = temp.next.next //要删除这个结点即直接略过这个结点,
		//然后这个被略过的结点会变成垃圾结点,会被链表删除
	} else {
		fmt.Println("要删除的id不存在")
	}
}
func modifyStudentNode(head *studentNode, id int, newStudentNode *studentNode) {
	temp := head
	flag := false
	//思路:
	//1.找到要修改的结点的no,和temp.next.no作比较
	for {
		if temp.next == nil { //说明已经到了链表的最后
			break
		} else if temp.next.no == id {
			//说明我们已经找到这个要修改的结点了
			flag = true
			break
		}
		temp = temp.next
	}
	if flag {
		temp.next = newStudentNode
	} else {
		fmt.Println("要修改的结点不存在")
	}
}

//显示链表的所有结点信息
func listStudentNode(head *studentNode) {
	//1.创建一个辅助结点
	temp := head
	//先判断该链表是不是一个空的链表
	if temp.next == nil {
		fmt.Println("这是一个空链表")
		return
	}
	//2.遍历这个链表
	for {
		fmt.Printf("[%d,%s,%d]==>", temp.next.no,
			temp.next.name, temp.next.age)
		//判断是否是链表的末尾
		temp = temp.next
		if temp.next == nil {
			break
		}
	}

}

func main() {
	//1.先创建一个头结点
	head := &studentNode{}
	//2.创建一个新的studentNode
	stuLisa := &studentNode{
		no:   1,
		name: "Lisa",
		age:  24,
	}
	stuBob := &studentNode{
		no:   2,
		name: "Bob",
		age:  25,
	}
	stuNick := &studentNode{
		no:   3,
		name: "Nick",
		age:  27,
	}
	stuMark := &studentNode{
		no:   4,
		name: "Mark",
		age:  29,
	}
	stuMarket := &studentNode{
		no:   4,
		name: "Market",
		age:  30,
	}
	//3.加入结点
	insertStudentNode(head, stuLisa)
	insertStudentNode(head, stuBob)

	//显示链表
	listStudentNode(head)
	fmt.Println()
	//4.加入结点(第二种方法)
	sortInsertStudentNode(head, stuMark) //no是4
	sortInsertStudentNode(head, stuNick) //no是3
	listStudentNode(head)
	fmt.Println()
	//5.删除结点
	delStudentNode(head, 2)
	//显示链表
	listStudentNode(head)
	fmt.Println()
	//6.修改结点
	modifyStudentNode(head, 4, stuMarket)
	listStudentNode(head)
}

你可能感兴趣的:(golang)