parent
ddc939fe45
commit
97674a6368
@ -1,105 +1,105 @@ |
|||||||
# If you prefer the allow list template instead of the deny list, see community template: |
# If you prefer the allow list template instead of the deny list, see community template: |
||||||
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore |
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore |
||||||
# |
# |
||||||
# Binaries for programs and plugins |
# Binaries for programs and plugins |
||||||
*.exe |
*.exe |
||||||
*.exe~ |
*.exe~ |
||||||
*.dll |
*.dll |
||||||
*.so |
*.so |
||||||
*.dylib |
*.dylib |
||||||
|
|
||||||
# Test binary, built with `go test -c` |
# Test binary, built with `go test -c` |
||||||
*.test |
*.test |
||||||
|
|
||||||
# Output of the go coverage tool, specifically when used with LiteIDE |
# Output of the go coverage tool, specifically when used with LiteIDE |
||||||
*.out |
*.out |
||||||
|
|
||||||
# Dependency directories (remove the comment below to include it) |
# Dependency directories (remove the comment below to include it) |
||||||
# vendor/ |
# vendor/ |
||||||
|
|
||||||
# Go workspace file |
# Go workspace file |
||||||
go.work |
go.work |
||||||
|
|
||||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider |
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider |
||||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 |
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 |
||||||
|
|
||||||
.idea |
.idea |
||||||
|
|
||||||
# User-specific stuff |
# User-specific stuff |
||||||
.idea/**/workspace.xml |
.idea/**/workspace.xml |
||||||
.idea/**/tasks.xml |
.idea/**/tasks.xml |
||||||
.idea/**/usage.statistics.xml |
.idea/**/usage.statistics.xml |
||||||
.idea/**/dictionaries |
.idea/**/dictionaries |
||||||
.idea/**/shelf |
.idea/**/shelf |
||||||
|
|
||||||
# AWS User-specific |
# AWS User-specific |
||||||
.idea/**/aws.xml |
.idea/**/aws.xml |
||||||
|
|
||||||
# Generated files |
# Generated files |
||||||
.idea/**/contentModel.xml |
.idea/**/contentModel.xml |
||||||
|
|
||||||
# Sensitive or high-churn files |
# Sensitive or high-churn files |
||||||
.idea/**/dataSources/ |
.idea/**/dataSources/ |
||||||
.idea/**/dataSources.ids |
.idea/**/dataSources.ids |
||||||
.idea/**/dataSources.local.xml |
.idea/**/dataSources.local.xml |
||||||
.idea/**/sqlDataSources.xml |
.idea/**/sqlDataSources.xml |
||||||
.idea/**/dynamic.xml |
.idea/**/dynamic.xml |
||||||
.idea/**/uiDesigner.xml |
.idea/**/uiDesigner.xml |
||||||
.idea/**/dbnavigator.xml |
.idea/**/dbnavigator.xml |
||||||
|
|
||||||
# Gradle |
# Gradle |
||||||
.idea/**/gradle.xml |
.idea/**/gradle.xml |
||||||
.idea/**/libraries |
.idea/**/libraries |
||||||
|
|
||||||
# Gradle and Maven with auto-import |
# Gradle and Maven with auto-import |
||||||
# When using Gradle or Maven with auto-import, you should exclude module files, |
# When using Gradle or Maven with auto-import, you should exclude module files, |
||||||
# since they will be recreated, and may cause churn. Uncomment if using |
# since they will be recreated, and may cause churn. Uncomment if using |
||||||
# auto-import. |
# auto-import. |
||||||
.idea/artifacts |
.idea/artifacts |
||||||
.idea/compiler.xml |
.idea/compiler.xml |
||||||
.idea/jarRepositories.xml |
.idea/jarRepositories.xml |
||||||
.idea/modules.xml |
.idea/modules.xml |
||||||
.idea/*.iml |
.idea/*.iml |
||||||
.idea/modules |
.idea/modules |
||||||
*.iml |
*.iml |
||||||
*.ipr |
*.ipr |
||||||
|
|
||||||
# CMake |
# CMake |
||||||
cmake-build-*/ |
cmake-build-*/ |
||||||
|
|
||||||
# Mongo Explorer plugin |
# Mongo Explorer plugin |
||||||
.idea/**/mongoSettings.xml |
.idea/**/mongoSettings.xml |
||||||
|
|
||||||
# File-based project format |
# File-based project format |
||||||
*.iws |
*.iws |
||||||
|
|
||||||
# IntelliJ |
# IntelliJ |
||||||
out/ |
out/ |
||||||
|
|
||||||
# mpeltonen/sbt-idea plugin |
# mpeltonen/sbt-idea plugin |
||||||
.idea_modules/ |
.idea_modules/ |
||||||
|
|
||||||
# JIRA plugin |
# JIRA plugin |
||||||
atlassian-ide-plugin.xml |
atlassian-ide-plugin.xml |
||||||
|
|
||||||
# Cursive Clojure plugin |
# Cursive Clojure plugin |
||||||
.idea/replstate.xml |
.idea/replstate.xml |
||||||
|
|
||||||
# SonarLint plugin |
# SonarLint plugin |
||||||
.idea/sonarlint/ |
.idea/sonarlint/ |
||||||
|
|
||||||
# Crashlytics plugin (for Android Studio and IntelliJ) |
# Crashlytics plugin (for Android Studio and IntelliJ) |
||||||
com_crashlytics_export_strings.xml |
com_crashlytics_export_strings.xml |
||||||
crashlytics.properties |
crashlytics.properties |
||||||
crashlytics-build.properties |
crashlytics-build.properties |
||||||
fabric.properties |
fabric.properties |
||||||
|
|
||||||
# Editor-based Rest Client |
# Editor-based Rest Client |
||||||
.idea/httpRequests |
.idea/httpRequests |
||||||
|
|
||||||
# Android studio 3.1+ serialized cache file |
# Android studio 3.1+ serialized cache file |
||||||
.idea/caches/build_file_checksums.ser |
.idea/caches/build_file_checksums.ser |
||||||
|
|
||||||
*.log |
*.log |
||||||
|
|
||||||
/config.yml |
/config.yml |
||||||
|
@ -1,32 +1,32 @@ |
|||||||
# Lavos |
# Lavos |
||||||
|
|
||||||
算法设计与分析例题/作业代码合集,使用go编写实现 |
算法设计与分析例题/作业代码合集,使用go编写实现 |
||||||
|
|
||||||
## 目录结构 |
## 目录结构 |
||||||
|
|
||||||
包代码目录格式为,`cap{x}`,对应的是第x章的例题和作业代码,其中每个例题/作业代码文件均命名为`ex{x}.go`以及`work{x}.go`。 |
包代码目录格式为,`cap{x}`,对应的是第x章的例题和作业代码,其中每个例题/作业代码文件均命名为`ex{x}.go`以及`work{x}.go`。 |
||||||
|
|
||||||
如第三章例6,位于`cap3/ex6.go`中,第四章作业5,位于`cap4/ex5.go`中。 |
如第三章例6,位于`cap3/ex6.go`中,第四章作业5,位于`cap4/ex5.go`中。 |
||||||
|
|
||||||
## 运行/测试 |
## 运行/测试 |
||||||
|
|
||||||
要运行测试,需要go开发环境。[Go installation instructions: https://go.dev/doc/install](https://go.dev/doc/install) |
要运行测试,需要go开发环境。[Go installation instructions: https://go.dev/doc/install](https://go.dev/doc/install) |
||||||
|
|
||||||
完成后,运行 |
完成后,运行 |
||||||
```shell |
```shell |
||||||
go test lavos/cap3 |
go test lavos/cap3 |
||||||
``` |
``` |
||||||
|
|
||||||
即可运行该章节下所有的例题和作业的test用例,例题和作业的test代码位于`example_test.go`和`work_test.go`中。 |
即可运行该章节下所有的例题和作业的test用例,例题和作业的test代码位于`example_test.go`和`work_test.go`中。 |
||||||
|
|
||||||
如果需要单独测试某一个题目,运行 |
如果需要单独测试某一个题目,运行 |
||||||
```shell |
```shell |
||||||
go test lavos/cap3 -v '-test.run' 'Ex6$' |
go test lavos/cap3 -v '-test.run' 'Ex6$' |
||||||
go test lavos/cap3 -v '-test.run' 'Work1$' |
go test lavos/cap3 -v '-test.run' 'Work1$' |
||||||
``` |
``` |
||||||
即可运行对应的题目,如示例中将会运行第三章例题6的test和作业1 |
即可运行对应的题目,如示例中将会运行第三章例题6的test和作业1 |
||||||
|
|
||||||
## 其他细节 |
## 其他细节 |
||||||
|
|
||||||
由于习惯原因,我并不是很喜欢在算法代码中进行具体的输出操作,或者直接将输出输入放置于算法代码中,而是使用了类似于leetcode中的核心代码模式,因此`ex{x}.go`和`work{x}.go`中的代码模式均为核心代码,不负责输出输入, |
由于习惯原因,我并不是很喜欢在算法代码中进行具体的输出操作,或者直接将输出输入放置于算法代码中,而是使用了类似于leetcode中的核心代码模式,因此`ex{x}.go`和`work{x}.go`中的代码模式均为核心代码,不负责输出输入, |
||||||
如有需要输出的算法,通过callback实现,传入能够实现输出的callback函数,在核心中调用callback来实现输出,核心代码不关心也不区负责输出输入,输出输入由test负责实现。 |
如有需要输出的算法,通过callback实现,传入能够实现输出的callback函数,在核心中调用callback来实现输出,核心代码不关心也不区负责输出输入,输出输入由test负责实现。 |
@ -1,25 +1,25 @@ |
|||||||
package cap3 |
package cap3 |
||||||
|
|
||||||
var _numberTexts = []string{ |
var _numberTexts = []string{ |
||||||
"zero", "one", "two", "three", "four", |
"zero", "one", "two", "three", "four", |
||||||
"five", "six", "seven", "eight", "nine", |
"five", "six", "seven", "eight", "nine", |
||||||
} |
} |
||||||
|
|
||||||
// Ex14NumInput 输入数字,输出英文
|
// Ex14NumInput 输入数字,输出英文
|
||||||
func Ex14NumInput(num uint64, callback func(str string)) { |
func Ex14NumInput(num uint64, callback func(str string)) { |
||||||
digits := make([]uint8, 0, 20) |
digits := make([]uint8, 0, 20) |
||||||
for i := num; i >= 1; i /= 10 { |
for i := num; i >= 1; i /= 10 { |
||||||
digits = append(digits, uint8(i%10)) |
digits = append(digits, uint8(i%10)) |
||||||
} |
} |
||||||
|
|
||||||
for i := len(digits) - 1; i >= 0; i-- { |
for i := len(digits) - 1; i >= 0; i-- { |
||||||
callback(_numberTexts[digits[i]]) |
callback(_numberTexts[digits[i]]) |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
// Ex14StrInput 输入数字字符串,输出英文
|
// Ex14StrInput 输入数字字符串,输出英文
|
||||||
func Ex14StrInput(num string, callback func(str string)) { |
func Ex14StrInput(num string, callback func(str string)) { |
||||||
for _, char := range num { |
for _, char := range num { |
||||||
callback(_numberTexts[char-48]) |
callback(_numberTexts[char-48]) |
||||||
} |
} |
||||||
} |
} |
||||||
|
@ -1,24 +1,24 @@ |
|||||||
package cap3 |
package cap3 |
||||||
|
|
||||||
var ( |
var ( |
||||||
cashes = []int{50, 20, 10, 5, 2, 1} |
cashes = []int{50, 20, 10, 5, 2, 1} |
||||||
) |
) |
||||||
|
|
||||||
// Ex15 最少的纸币找零钱
|
// Ex15 最少的纸币找零钱
|
||||||
func Ex15(amount, paid int) map[int]int { |
func Ex15(amount, paid int) map[int]int { |
||||||
result := map[int]int{} |
result := map[int]int{} |
||||||
|
|
||||||
// 还要找的钱
|
// 还要找的钱
|
||||||
change := paid - amount |
change := paid - amount |
||||||
for i, cash := range cashes { |
for i, cash := range cashes { |
||||||
// 当前面额需要找的张数,整除后结果为0说明当前面额不足以找零
|
// 当前面额需要找的张数,整除后结果为0说明当前面额不足以找零
|
||||||
cashNum := change / cash |
cashNum := change / cash |
||||||
if cashNum != 0 { |
if cashNum != 0 { |
||||||
result[i] = cashNum |
result[i] = cashNum |
||||||
// 当前面额找完后更新剩余未找余额
|
// 当前面额找完后更新剩余未找余额
|
||||||
change = change - cashNum*cash |
change = change - cashNum*cash |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
return result |
return result |
||||||
} |
} |
||||||
|
@ -1,107 +1,107 @@ |
|||||||
package cap3 |
package cap3 |
||||||
|
|
||||||
import ( |
import ( |
||||||
"strings" |
"strings" |
||||||
) |
) |
||||||
|
|
||||||
// Ex18 超长整数乘法(都超长)
|
// Ex18 超长整数乘法(都超长)
|
||||||
func Ex18(a, b string) string { |
func Ex18(a, b string) string { |
||||||
result := make([]uint8, len(a)+len(b)) |
result := make([]uint8, len(a)+len(b)) |
||||||
resultEndIdx := len(result) - 1 |
resultEndIdx := len(result) - 1 |
||||||
for i := 0; i < len(b); i++ { |
for i := 0; i < len(b); i++ { |
||||||
carry := uint8(0) |
carry := uint8(0) |
||||||
aEnd, bEnd, resultIdx := len(a)-1, len(b)-1, 0 |
aEnd, bEnd, resultIdx := len(a)-1, len(b)-1, 0 |
||||||
bDigit := b[bEnd-i] - 48 |
bDigit := b[bEnd-i] - 48 |
||||||
for j := 0; j < len(a); j++ { |
for j := 0; j < len(a); j++ { |
||||||
// 字符转数字
|
// 字符转数字
|
||||||
aDigit := a[aEnd-j] - 48 |
aDigit := a[aEnd-j] - 48 |
||||||
// 当前位计算结果 = 当前结果 + aDigit*bDigit + 进位
|
// 当前位计算结果 = 当前结果 + aDigit*bDigit + 进位
|
||||||
resultIdx = resultEndIdx - (i + j) |
resultIdx = resultEndIdx - (i + j) |
||||||
num := result[resultIdx] + aDigit*bDigit + carry |
num := result[resultIdx] + aDigit*bDigit + carry |
||||||
// 当前位为计算结果的个位,进位为十位上的数字
|
// 当前位为计算结果的个位,进位为十位上的数字
|
||||||
result[resultIdx] = num % 10 |
result[resultIdx] = num % 10 |
||||||
carry = num / 10 |
carry = num / 10 |
||||||
} |
} |
||||||
|
|
||||||
// 如果还有进位,则对下一个结果位添加进位,此时不会再有进位
|
// 如果还有进位,则对下一个结果位添加进位,此时不会再有进位
|
||||||
if carry != 0 { |
if carry != 0 { |
||||||
resultIdx-- |
resultIdx-- |
||||||
result[resultIdx] += carry |
result[resultIdx] += carry |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
zeroPrefix := true |
zeroPrefix := true |
||||||
sb := strings.Builder{} |
sb := strings.Builder{} |
||||||
for _, num := range result { |
for _, num := range result { |
||||||
if zeroPrefix && num == 0 { |
if zeroPrefix && num == 0 { |
||||||
continue |
continue |
||||||
} else { |
} else { |
||||||
zeroPrefix = false |
zeroPrefix = false |
||||||
} |
} |
||||||
|
|
||||||
sb.WriteByte(num + 48) |
sb.WriteByte(num + 48) |
||||||
} |
} |
||||||
|
|
||||||
return sb.String() |
return sb.String() |
||||||
} |
} |
||||||
|
|
||||||
// Ex18type2 超长整数乘法(都超长),a和b都是大端序的数字数组/切片
|
// Ex18type2 超长整数乘法(都超长),a和b都是大端序的数字数组/切片
|
||||||
func Ex18type2(a, b []uint8) []uint8 { |
func Ex18type2(a, b []uint8) []uint8 { |
||||||
result := make([]uint8, len(a)+len(b)) |
result := make([]uint8, len(a)+len(b)) |
||||||
resultEndIdx := len(result) - 1 |
resultEndIdx := len(result) - 1 |
||||||
for i := 0; i < len(b); i++ { |
for i := 0; i < len(b); i++ { |
||||||
carry := uint8(0) |
carry := uint8(0) |
||||||
aEnd, bEnd, resultIdx := len(a)-1, len(b)-1, 0 |
aEnd, bEnd, resultIdx := len(a)-1, len(b)-1, 0 |
||||||
bDigit := b[bEnd-i] |
bDigit := b[bEnd-i] |
||||||
for j := 0; j < len(a); j++ { |
for j := 0; j < len(a); j++ { |
||||||
// 字符转数字
|
// 字符转数字
|
||||||
aDigit := a[aEnd-j] |
aDigit := a[aEnd-j] |
||||||
// 当前位计算结果 = 当前结果 + aDigit*bDigit + 进位
|
// 当前位计算结果 = 当前结果 + aDigit*bDigit + 进位
|
||||||
resultIdx = resultEndIdx - (i + j) |
resultIdx = resultEndIdx - (i + j) |
||||||
num := result[resultIdx] + aDigit*bDigit + carry |
num := result[resultIdx] + aDigit*bDigit + carry |
||||||
// 当前位为计算结果的个位,进位为十位上的数字
|
// 当前位为计算结果的个位,进位为十位上的数字
|
||||||
result[resultIdx] = num % 10 |
result[resultIdx] = num % 10 |
||||||
carry = num / 10 |
carry = num / 10 |
||||||
} |
} |
||||||
|
|
||||||
// 如果还有进位,则对下一个结果位添加进位,此时不会再有进位
|
// 如果还有进位,则对下一个结果位添加进位,此时不会再有进位
|
||||||
if carry != 0 { |
if carry != 0 { |
||||||
resultIdx-- |
resultIdx-- |
||||||
result[resultIdx] += carry |
result[resultIdx] += carry |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
return result |
return result |
||||||
} |
} |
||||||
|
|
||||||
// Ex18type3 超长整数乘法(都超长),a是大端序的数字数组/切片,b为uint64
|
// Ex18type3 超长整数乘法(都超长),a是大端序的数字数组/切片,b为uint64
|
||||||
func Ex18type3(a []uint8, b uint64) []uint8 { |
func Ex18type3(a []uint8, b uint64) []uint8 { |
||||||
result := make([]uint8, len(a)+22) |
result := make([]uint8, len(a)+22) |
||||||
resultEndIdx := len(result) - 1 |
resultEndIdx := len(result) - 1 |
||||||
bOffset := 0 |
bOffset := 0 |
||||||
for i := b; i >= 1; i /= 10 { |
for i := b; i >= 1; i /= 10 { |
||||||
carry := uint8(0) |
carry := uint8(0) |
||||||
bDigit := uint8(i % 10) |
bDigit := uint8(i % 10) |
||||||
aEnd, resultIdx := len(a)-1, 0 |
aEnd, resultIdx := len(a)-1, 0 |
||||||
for j := 0; j < len(a); j++ { |
for j := 0; j < len(a); j++ { |
||||||
// 字符转数字
|
// 字符转数字
|
||||||
aDigit := a[aEnd-j] |
aDigit := a[aEnd-j] |
||||||
// 当前位计算结果 = 当前结果 + aDigit*bDigit + 进位
|
// 当前位计算结果 = 当前结果 + aDigit*bDigit + 进位
|
||||||
resultIdx = resultEndIdx - (bOffset + j) |
resultIdx = resultEndIdx - (bOffset + j) |
||||||
num := result[resultIdx] + aDigit*bDigit + carry |
num := result[resultIdx] + aDigit*bDigit + carry |
||||||
// 当前位为计算结果的个位,进位为十位上的数字
|
// 当前位为计算结果的个位,进位为十位上的数字
|
||||||
result[resultIdx] = num % 10 |
result[resultIdx] = num % 10 |
||||||
carry = num / 10 |
carry = num / 10 |
||||||
} |
} |
||||||
|
|
||||||
// 如果还有进位,则对下一个结果位添加进位,此时不会再有进位
|
// 如果还有进位,则对下一个结果位添加进位,此时不会再有进位
|
||||||
if carry != 0 { |
if carry != 0 { |
||||||
resultIdx-- |
resultIdx-- |
||||||
result[resultIdx] += carry |
result[resultIdx] += carry |
||||||
} |
} |
||||||
|
|
||||||
bOffset++ |
bOffset++ |
||||||
} |
} |
||||||
|
|
||||||
return result |
return result |
||||||
} |
} |
||||||
|
Loading…
Reference in new issue