编程练习题(练习版)

1.递归的考察

请说明下面这段代码的输出结果。 2023.08.25

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
func main() {
	test(4)
}

func test(n int) {
    if n > 2 {
       n--
       test(n)
    }
    fmt.Println("n=", n)
}

练习记录:

2.闭包的使用

2023.08.25

  1. 编写一个函数 makeSuffix(suffix string) 可以接收一个文件后缀名(比如jpg),并返回一个闭包。
  2. 调用闭包,可以传入一个文件名,如果该文件名没有指定的后缀(比如.jpg) ,则返回 文件名.jpg,如果已经有.jpg后缀,则返回原文件名。
  3. 要求使用闭包的方式完成。
  4. strings.HasSuffix:func HasSuffix(s, suffix string) bool,判断s是否有后缀字符串suffix。

练习记录:

3.冒泡排序

2023.08.29

练习记录:

2023.10.17 成功!

2023.10.23 成功!

4.快速排序

2023.08.29

练习记录:

2023.10.17 关于边界的控制还是存在一点问题。

2023.10.18 成功!

2023.10.23 成功!

5.二分查找

2023.08.29

练习记录:

2023.10.17 成功!

6.自定义排序

2023.08.30

使用 sort.Sort(data Interface),实现对 Student 结构体切片的排序。

Student 结构体有三个字段:name string, age int, score int。

Student 结构体切片中存有多个 Student 对象,将这些对象按照 age 字段升序排列后遍历输出。

练习记录:

7.连续因子

2023.09.03

一个正整数 N 的因子中可能存在若干连续的数字。例如 630 可以分解为 3×5×6×7,其中 5、6、7 就是 3 个连续的数字。给定任一正整数 N,要求编写程序求出最长连续因子的个数,并输出最小的连续因子序列。

输入格式:

输入在一行中给出一个正整数 N(1<N<231)。

输出格式:

首先在第 1 行输出最长连续因子的个数;然后在第 2 行中按 因子1*因子2*……*因子k 的格式输出最小的连续因子序列,其中因子按递增顺序输出,1 不算在内。

输入样例:

1
630

输出样例:

1
2
3
5*6*7

练习记录:

8.查验身份证

2023.09.04

L1-016 查验身份证

一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。校验码的计算规则如下:

首先对前17位数字加权求和,权重分配为:{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};然后将计算的和对11取模得到值Z;最后按照以下关系对应Z值与校验码M的值:

1
2
Z:0 1 2 3 4 5 6 7 8 9 10
M:1 0 X 9 8 7 6 5 4 3 2

现在给定一些身份证号码,请你验证校验码的有效性,并输出有问题的号码。

输入格式:

输入第一行给出正整数N(≤100)是输入的身份证号码的个数。随后N行,每行给出1个18位身份证号码。

输出格式:

按照输入的顺序每行输出1个有问题的身份证号码。这里并不检验前17位是否合理,只检查前17位是否全为数字且最后1位校验码计算准确。如果所有号码都正常,则输出All passed

输入样例1:

1
2
3
4
5
4
320124198808240056
12010X198901011234
110108196711301866
37070419881216001X

输出样例1:

1
2
3
12010X198901011234
110108196711301866
37070419881216001X

输入样例2:

1
2
3
2
320124198808240056
110108196711301862

输出样例2:

1
All passed

练习记录:

9.字符串转换为整数

2023.09.25

题目描述:实现一个函数 Atoi(s string) (int64, error),该函数将一个字符串 s 解析为一个带符号的整数,并返回解析后的整数值和错误。如果解析失败,应返回适当的错误。

要求:

  1. 函数的输入参数 s 是一个字符串,表示要解析的整数。
  2. 函数应能处理正整数和负整数。
  3. 函数的返回值应为解析后的整数和一个错误。如果解析成功,错误应该为 nil,否则应包含错误信息。
  4. 不考虑超出int64范围越界的问题。

示例:

1
2
3
4
5
6
7
8
val, err := Atoi("123")
// val 应该为 123,err 应该为 nil

val, err := Atoi("-456")
// val 应该为 -456,err 应该为 nil

val, err := Atoi("12a34")
// val 应该为 0,err 应该包含合适的错误信息

请实现上述要求并编写 Atoi 函数的完整代码。

练习记录:

2023.10.18 成功!

10.单例模式

2023.10.07

手写一个单例模式的代码,并测试创建实例的函数创建的实例对象都是同一个。

练习记录:

2023.10.17 没写出来,忘了Once函数的写法;自己加锁也不知道该如何返回创建的实例。

11.循环定时任务

2023.10.07

创建一个可以循环执行的定时任务,要求可以指定任务的次数,当达到指定执行次数时,程序退出。

练习记录:

2023.10.18 失败,完全忘记了定时器的用法。

12.对象池

2023.10.07

实现一个简单的对象池的功能,要求:

  • 通过NewObjPool(numOfObj int)函数设置连接池的大小,并初始化连接池。
  • 通过GetObj(timeout time.Duration)可以获取一个连接池对象,timeout 参数为指定的超时时间(当操作指定时间还没有获取到连接池对象时,报超时的错误)。
  • 通过ReleaseObj(obj *ReusableObj)函数可以将一个连接池对象放入连接池中。
  • 测试连接池的所有功能。

思考使用什么数据结构可以更好地实现连接池?

练习记录:

2023.10.18 失败,对于超时的控制还不能完成。

13.生成随机字符串

2023.10.07

定义一个GetRandomString(n int)函数,生成随机的字符串(包含数字和小写英文字母),可以指定字符串的位数n。

练习记录:

2023.10.18 在指定随机数种子时,存在一些问题。

14.删除数组中的重复元素

2023.10.07

定义函数removeDuplicates(array []int),删除数组中的重复元素。

练习记录:

15.反射的最佳实践

2023.10.07

使用反射的方式来获取结构体的tag标签,遍历字段的值,修改字段值,调用结构体方法。

具体的结构体和结构体方法如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
type Mankind struct {
    Name   string `json:"name"`
    Age    int    `json:"age"`
    Gender string `json:"gender"`
}

func (m *Mankind) Introduce() {
    fmt.Printf("My name is %v, %v years old!\n", m.Name, m.Age)
}

func main() {
	m1 := Mankind{"Jerry", 25, "male"}
    // 定义名为callStructure的函数,完成题目要求的功能。
}
func callStructure() {

练习记录:

16.单向环形队列

2023.10.11

使用数组模拟实现一个单向的环形队列,只要不超过队列的最大长度,就可以一直利用数组队列的空间,不断地进行Push和Pop操作,要求实现三个方法:Push(添加元素)、Pop(取出元素)、ShowQueue(显示队列所有元素)。

练习记录:

2023.10.17 成功!

17.约瑟夫问题

2023.10.12

题目描述:

你需要实现一个Josephus环,该环包含一定数量的成员。每个成员都有一个唯一的ID。

要求:

  1. 编写函数InitRing ,来初始化Josephus环。
  2. 编写函数GetRingElems,打印出Josephus环中所有的成员ID。
  3. 编写函数 PlayGame,以模拟Josephus问题的解决过程。

具体要求如下:

  • 从环中的第 startNo 号成员开始,数数,数到第 countNo 号成员后,将其从环中淘汰。
  • 淘汰后,重新从下一个成员开始数,继续数 countNo 个成员,再淘汰。
  • 重复上述过程,直到只剩下一个成员为止。

三个函数的签名如下:

1
2
3
4
5
6
func InitRing(num int) *JosephusRing{}  // num:初始化成员的数量
func GetRingElems(first *JosephusRing) {}  // first:Josephus环的第一个成员的指针
func PlayGame(first *JosephusRing, startNo int, countNo int) {}  
// first:Josephus环的第一个成员的指针
// startNo:开始计数的成员的ID号(从1开始)。
// countNo:每次数数的步数。

练习记录:

18.选择排序

2023.10.14

练习记录:

2023.10.17 成功!

2023.10.23 成功!

19.插入排序

2023.10.14

练习记录:

2023.10.17 成功!

2023.10.23 成功!

20.Hash表

2023.10.15

实现一个简单的哈希表,然后要求你编写插入、查找和删除键值对的操作。

问题描述:

你需要实现一个简单的哈希表(不要使用Go的内置map),该哈希表支持以下操作:

  1. Insert(key string, value int):插入一个键值对,如果键已存在,则更新其值。
  2. Get(key string) int:获取给定键对应的值,如果键不存在,则返回 -1。
  3. Delete(key string):从哈希表中删除给定键的键值对。

你的哈希表应该能够处理哈希碰撞,可以使用开放寻址法或链表法等方法来解决碰撞问题。你可以使用已经实现的哈希函数或自己编写一个哈希函数。

示例使用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
func main() {
    myHashMap := Constructor() // 创建哈希表实例

    myHashMap.Insert("apple", 1) // 插入键值对
    myHashMap.Insert("banana", 2)
    myHashMap.Insert("cherry", 3)

    fmt.Println(myHashMap.Get("apple")) // 输出: 1
    fmt.Println(myHashMap.Get("banana")) // 输出: 2

    myHashMap.Delete("banana") // 删除键值对
    fmt.Println(myHashMap.Get("banana")) // 输出: -1
}

练习记录:

21.归并排序

2023.10.16

练习记录:

2023.10.17 存在部分问题,范围没控制好。

2023.10.18 成功!

2023.10.23 成功!经过调试,虽然最后写的代码存在冗余,但结果是正确的。

22.和等于k的最长子数组长度

2023.10.17

力扣:和等于 k 的最长子数组长度 给定一个数组nums和一个目标值k,找到累加和等于k的最长连续子数组长度。如果不存在任意一个符合要求的子数组,则返回 0。

练习记录:

2023.10.17 成功!

23.荷兰国旗问题

2023.10.17

给定一个数组arr,和一个整数num,请把小于num的数放在数组的左边,等于num的数放在数组的中间,大于num的数放在数的右边。 要求额外空间复杂度O(1),时间复杂度O(N)。

练习记录:

2023.10.17 失败,不知道如何确定值等于num的元素位置。

2023.10.23 成功!

24.找到第K大的数

2023.10.18

给你一个整数数组nums和一个正数k,请你返回第k大的数。要求时间复杂度O(n)。

练习记录:

2023.10.23 失败,对于分区之后的左右边界的控制存在问题。

25.大根堆

2023.10.18

创建一个 MaxHeap 结构体,其中包含最大堆的堆切片和堆大小。它包括了插入元素、删除最大元素、堆化(上浮和下沉)操作。在 main 函数中,使用最大堆来插入元素并删除最大元素(依次输出堆中最大的元素)。

练习记录:

26.堆排序

2023.10.19

练习记录:

2023.10.19 heapify的过程写得还是存在部分问题。

0%