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