https://leetcode.com/problems/longest-word-in-dictionary/description/
Given a list of strings words representing an English Dictionary, find the longest word in words that can be built one character at a time by other words in words. If there is more than one possible answer, return the longest word with the smallest lexicographical order. If there is no answer, return the empty string.
Example 1:
Input:
words = ["w","wo","wor","worl", "world"]
Output: "world"
Explanation:
The word "world" can be built one character at a time by "w", "wo", "wor", and "worl".
Example 2:
Input:
words = ["a", "banana", "app", "appl", "ap", "apply", "apple"]
Output: "apple"
Explanation:
Both "apply" and "apple" can be built from other words in the dictionary. However, "apple" is lexicographically smaller than "apply".
Note:
package main
import (
"sort"
"fmt"
)
type SortByString []string
func (s SortByString) Len() int {
return len(s)
}
func (s SortByString) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s SortByString) Less(i, j int) bool {
return s[i] < s[j]
}
func longestWord(words []string) string {
lWord := ""
m := make(map[string]bool)
fmt.Println(words)
sort.Sort(SortByString(words))
fmt.Println(words)
for _, v := range words {
bSuccess := false
if len(v) == 1 {
m[v] = true
bSuccess = true
} else {
prefix := v[:len(v)-1]
fmt.Println("v = ", v, ", prefix = ", prefix)
if _, ok := m[prefix]; ok {
m[v] = true
bSuccess = true
}
}
if bSuccess {
if lWord == "" {
lWord = v
} else {
if (len(v) > len(lWord)) || (len(v) == len(lWord) && v < lWord) {
lWord = v
}
}
}
}
return lWord
}
func main() {
words := []string{
"w", "wo", "wor", "worl", "world",
}
ret := longestWord(words)
fmt.Println("ret = ", ret)
}
1. 给fork配置一个remote
Administrator@ROEGRBXEPPWF49V MINGW64 /e/git
$ cd GCTT
Administrator@ROEGRBXEPPWF49V MINGW64 /e/git/GCTT (master)
$ git remote -v
origin https://github.com/MDGSF/GCTT.git (fetch)
origin https://github.com/MDGSF/GCTT.git (push)
Administrator@ROEGRBXEPPWF49V MINGW64 /e/git/GCTT (master)
$ git branch
* master
Administrator@ROEGRBXEPPWF49V MINGW64 /e/git/GCTT (master)
$ git remote add upstream https://github.com/studygolang/GCTT
Administrator@ROEGRBXEPPWF49V MINGW64 /e/git/GCTT (master)
$ git remote -v
origin https://github.com/MDGSF/GCTT.git (fetch)
origin https://github.com/MDGSF/GCTT.git (push)
upstream https://github.com/studygolang/GCTT (fetch)
upstream https://github.com/studygolang/GCTT (push)
Administrator@ROEGRBXEPPWF49V MINGW64 /e/git/GCTT (master)
$ git branch
* master
2. 从上游仓库 fetch 分支和提交点,传送到本地,并会被存储在一个本地分支 upstream/master
Administrator@ROEGRBXEPPWF49V MINGW64 /e/git/GCTT (master)
$ git fetch upstream
remote: Counting objects: 74, done.
remote: Compressing objects: 100% (32/32), done.
remote: Total 74 (delta 50), reused 65 (delta 42), pack-reused 0
Unpacking objects: 100% (74/74), done.
From https://github.com/studygolang/GCTT
* [new branch] master -> upstream/master
Administrator@ROEGRBXEPPWF49V MINGW64 /e/git/GCTT (master)
$ git branch
* master
3. 把 upstream/master 分支合并到本地 master 上
Administrator@ROEGRBXEPPWF49V MINGW64 /e/git/GCTT (master)
$ git merge upstream/master
Auto-merging published/tech/为 Go Web-apps 编写 Dockerfiles 的终极指南.md
Auto-merging published/tech/Go语言的错误处理.md
Merge made by the 'recursive' strategy.
...224\231\350\257\257\345\244\204\347\220\206.md" | 118 ++---
...273\210\346\236\201\346\214\207\345\215\227.md" | 53 ++-
.../tech/Language Mechanics On Memory Profiling.md | 497 +++++++++++++++++++++
.../Language Mechanics On Stacks And Pointers.md | 290 ++++++++++++
.../Using Go as a scripting language in Linux.md | 145 ++++++
5 files changed, 1019 insertions(+), 84 deletions(-)
rename "translated/tech/Go\350\257\255\350\250\200\347\232\204\351\224\231\350\257\257\345\244\204\347\220\206.md" => "published/tech/Go\350\257\255\350\250\200\347\232\204\351\224\231\350\257\257\345\244\204\347\220\206.md" (80%)
rename "translated/tech/\344\270\272 Go Web-apps \347\274\226\345\206\231 Dockerfiles \347\232\204\347\273\210\346\236\201\346\214\207\345\215\227.md" => "published/tech/\344\270\272 Go Web-apps \347\274\226\345\206\231 Dockerfiles \347\232\204\347\273\210\346\236\201\346\214\207\345\215\227.md" (95%)
create mode 100644 translated/tech/Language Mechanics On Memory Profiling.md
create mode 100644 translated/tech/Language Mechanics On Stacks And Pointers.md
create mode 100644 translated/tech/Using Go as a scripting language in Linux.md
4. 更新到GitHub的fork上去
Administrator@ROEGRBXEPPWF49V MINGW64 /e/git/GCTT (master)
$ git push origin master
fatal: HttpRequestException encountered.
An error occurred while sending the request.
Username for 'https://github.com': 1342042894@qq.com
Password for 'https://1342042894@qq.com@github.com':
Counting objects: 78, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (78/78), done.
Writing objects: 100% (78/78), 42.00 KiB | 3.23 MiB/s, done.
Total 78 (delta 53), reused 0 (delta 0)
remote: Resolving deltas: 100% (53/53), completed with 5 local objects.
To https://github.com/MDGSF/GCTT.git
4f2b86d..3624816 master -> master
https://gaohaoyang.github.io/2015/04/12/Syncing-a-fork/
https://help.github.com/articles/configuring-a-remote-for-a-fork/
在这篇文章中,我将会讨论为什么你应该尝试下 Go 语言,并且应该从哪里开始下手。
Golang 是一种编程语言,在过去的几年中你可能听说过很多。尽管是在 2009 年创建的,但是近年来才开始流行。
上图是根据 Google Trends 得出的 Golang 的流行程度
本文不是关于你通常看到的 Go 的主要卖点。
相反,我想向你介绍一些相当小但仍然很重要的功能,你只有在决定尝试 Go 之后才能了解到这些功能。
这些令人惊叹的特性没有浮于表面,它们可以为你节省大量的工作。它们还可以使软件开发更加愉快。
如果 Go 对你来说是新事物,别担心。本文不需要任何 Go 语言经验。如果你想了解更多,我已经在文章底部添加了一些额外的链接。
我们将会涉及以下主题:
请注意,列表不遵循任何特定的顺序。它也被视为地狱。
Go 非常重视代码中的文档。所以这变得很简单。
GoDoc 是一个静态代码分析工具,可以直接从你的代码中创建出漂亮的文档页面。关于 GoDoc 的一个值得注意的事情是,它不使用任何额外的语言,就像 JavaDoc,PHPDoc 或 JSDoc 在代码中的注释结构一样。仅仅只使用英语。
它尽可能多的使用从代码中获取的信息,来构建文档的轮廓,结构化和格式化文档。它具有所有的花里胡哨的东西,比如交叉引用,代码示例和直接链接到版本控制系统库。
所有你能做的就是添加一个好的 // MyFunc transforms Foo into Bar
注释,这也将会在文档中体现出来。你甚至可以添加代码示例,它可以通过 Web 界面或在本地实际运行。
GoDoc 是整个社区使用的唯一的 Go 文档引擎。这意味着用 Go 编写的每个库或应用程序都具有相同的文档格式。从长远来看,它帮你节省了大量浏览这些文档的时间。
举个例子,这是我最近实现的示例项目的 GoDoc 页面:pullkee — GoDoc。
Go 重度依赖于静态代码分析。例如,包括用于文档的 godoc,用于代码格式化的 gofmt,用于代码风格检查的 golint,以及许多其他的例子。
有这么多的工具,甚至有一个叫 gometalinter 的项目,能够把所有的工具打包组合成一个单一的工具。
这些工具通常作为独立的命令行应用程序来实现,并可以轻松地集成到任何编码环境。
静态代码分析实际上并不是现代编程中的新东西,但是 Go 把它用到了极致。我不能高估它为我节省了多少时间。另外,它会给你一种安全的感觉,好像有人在你的背后替你遮挡风雨。
创建自己的分析工具非常容易,因为 Go 有专门的内置软件包可以用来解析和处理 Go 源代码。
你可以从这个演讲中了解更多:GothamGo Kickoff Meetup: Go Static Analysis Tools by Alan Donovan.
你有没有试过为一个从头开始的 Javascript 项目选择一个测试框架?如果是这样,你可能会明白,经历这样一个分析瘫痪的斗争。你也许已经意识到你并没有使用你所选择框架的 80%。
一旦你需要做一些可靠的分析,这个问题就会重复出现。
Go 提供了一个内置的测试工具,旨在简化和高效。它为你提供了最简单可用的 API,并做出了最小的假设。你可以将其用于不同类型的测试,分析,甚至提供可执行的代码示例。
它开箱即用,能够生成了 CI 友好的输出,使用方法通常和运行 go test
一样简单。当然,它也支持高级功能,如并行运行测试,标记跳过,等等。
你可能已经知道 Goroutines,它在 Go 中用于实现并发代码执行。如果你还不了解它,这里有一个非常简短的解释。
在复杂的应用程序中进行并发编程并不容易,不管具体的技术如何,部分原因在于竞争条件的可能性。
简而言之,当多个并发操作以不可预知的顺序完成时,竞争条件就会发生。这可能会导致大量的错误,特别难以追查。有没有花了一天的时间去调试一个只能执行大约 80% 情况的集成测试呢?这可能是一个竞争条件。
所有这一切表明,并发编程在 Go 中非常受重视,幸运的是,我们有相当强大的工具来捕捉这些竞争条件。它被完全集成到 Go 的工具链中。
你可以在这里阅读更多关于它的信息,并学习如何使用它:Introducing the Go Race Detector — The Go Blog.
你可以在一个晚上学习完 Go 语言的所有功能。我是认真的。当然,还有标准库,以及不同的,更具体的领域的最佳实践。但是,两个小时完全足够让你自信地写出一个简单的 HTTP 服务器或命令行应用程序。
这个项目有非常棒的文档,大部分的高级主题已经被他们的博客所覆盖:The Go Programming Language Blog。
Go 比 Java(和它的家族成员),Javascript,Ruby,Python 甚至 PHP 更容易在你的团队普及。Go 的开发环境很容易设置,你的团队只需要做很小的投资,就能完成你的第一个产品代码。
代码反射本质上是一种能力,可以潜藏在屏幕下方,访问有关语言结构的各种元信息,如变量或函数。
鉴于 Go 是一种静态类型的语言,当涉及更松散的类型抽象编程时,它会受到各种限制。特别是与 Javascript 或 Python 等语言相比。
而且,Go 没有实现一个被称为泛型的概念,这使得以抽象的方式处理多种类型更具挑战性。然而,由于泛型带来的复杂性,许多人认为这对语言实际上是有益的。我完全同意。
根据 Go 的设计哲学理念(这本身是一个独立的话题),你应该尽量不要过度设计你的解决方案。这也适用于动态类型编程。尽可能地坚持使用静态类型,当你明确知道你正在处理什么类型时使用接口。在 Go 中,接口非常强大,无处不在。
但是,仍然有些情况下你不可能知道你所面对的是哪种数据。JSON 就是一个很好的例子。你可以在应用程序中来回转换所有类型的数据。字符串,缓冲区,各种数字,嵌套结构等等。
为了解决这个问题,你需要一个工具来检查运行时的所有数据,根据数据类型和结构的不同而采取不同的行为。反射能够帮助你!Go 有一个一等公民的反射包,它使你的代码可以是动态的,就像 JavaScript 这样的语言。
一个重要的警告是要知道你使用它付出了什么样的代价 – 只有在没有简单的方法时才使用它。
你可以在这里读到更多关于它的内容:The Laws of Reflection — The Go Blog.
你也可以在这里阅读 JSON 包源代码中的一些真实代码:src/encoding/json/encode.go — Source Code
顺便说一句,有这样一个词吗?
在 Javascript 的世界里,我面临的最艰巨的事情之一是决定我需要使用哪些约定和工具。我应该如何格式化我的代码?我应该使用什么测试库?我应该怎么去设计结构?我应该依靠什么样的编程模式和方法?
有时这些东西基本上让我卡住了。我不得不做这些事情,而无法把时间花在写代码、满足用户需求上。
首先,我应该注意到,我完全知道这些公约应该来自哪里。这总是来自你和你的团队。无论如何,即使是一群经验丰富的 Javascript 开发人员也可以很容易地发现自己使用完全不同的工具和约定,来达到相同的结果。
这使得在整个团队中分析定位问题很困难,也使得每个人难以互相合作。
但是,Go 是不同的。你只有一份每个人都必须遵循的代码风格指南。你只有一个内置于基本工具链中的测试框架。关于如何构建和维护代码,你有很多强烈的意见。如何选择名称。遵循什么样的结构化模式。如何更好地执行并发。
虽然这可能看起来过于严格,但这能够为你和你的团队节省了大量的时间。当你编码时,有些限制是一件很好的事情。在构建新的代码时,它给了你一个更直接的方法,并且更容易理解现有的代码。
因此,大部分 Go 项目看起来都非常相似。
人们都说,每当你学习一种新的口语时,你也会受到说这种语言的人的文化的部分熏陶。因此,你学习的语言越多,你可能受到的更多的个人改变。
这与编程语言是一样的。无论将来使用何种新的编程语言,它总是会给你一个关于编程的新观点,或者一些特定的技术。
无论是函数式编程,模式匹配还是原型继承。一旦你掌握了这些知识,就可以随身携带这些方法,从而拓宽了你作为一个软件开发人员解决问题的工具。通常来说它也改变了你看待高质量编程的方式。
Go 是一个很好的投资机会。Go 文化的主要支柱是保持简单实用的代码,而不会产生多余的抽象,并且非常重视代码的可维护性。能够把大量时间用在实现业务代码上,而不是用来修改工具和配置环境,这也是文化的一部分。或者在不同的变体之间进行选择。
Go 也可以总结为“应该只有一个方法来完成一件事情”。
一个小方面的说明。当你需要构建一个相对复杂的抽象时,用 Go 通常不是那么好实现的。对于这点,这应该是 Go 语言简单性的一种代价。
如果你真的需要编写大量的具有复杂关系的抽象代码,最好使用像 Java 或 Python 这样的语言。但是,即使真的有需要,这种情况也是非常罕见的。
始终使用最好的工具来完成工作!
你以前可能听说过 Go。或者也许它一直不在你的使用范围之内。无论哪种方式,Go 可以是你或你的团队在开始新项目或改进现有项目时一个非常体面的选择。
这并不是关于 Go 的所有令人惊叹的优点的完整列表。仅仅只是被低估的部分。
请尝试一下 Go 语言,A Tour of Go 是一个很好的开始学习的地方。
如果你想了解更多关于 Go 的好处,你可以看看这些链接:
在评论中分享你的学习结果!
即使你没有在专门寻找一种新的语言,花一两个小时的时间了解下 Go 也是值得的。也许在未来可能会变得对你非常有用。
持续不断的寻找最适合你的开发工具!
如果你喜欢这篇文章,请考虑关注我的更多内容,并点击这些文本下面的那些有趣的绿色小手来分享。👏👏👏
via: https://medium.freecodecamp.org/here-are-some-amazing-advantages-of-go-that-you-dont-hear-much-about-1af99de3b23a
作者:Kirill Rogovoy 译者:MDGSF 校对:校对者ID
每一天,或者是每隔几天,总有人来到 /r/golang ,并询问些类似如下的问题“哪个框架是最好的?”。我认为我们应该尝试提出这个问题,至少以一种容易理解的方式提出。你不应该使用框架。
对于一个复杂的问题,这也许是一个非常简洁的答案。这并不是说你任何时候都不应该使用框架。众所周知,当我们开发软件的时候,有这么一种趋势,慢慢形成适应通用开发的模式,并且一次又一次地加快开发同样的东西。它试着尽可能的消除重复代码。
Go 语言标准库的质量很高。你应该尽可能的使用它。如果你正在编写 API 服务,你需要熟悉 net/http
包,而且你最终无论使用哪个框架都是基于这个包的。将第三方包导入标准库是需要认真考虑的,当他们解决的是一个非常专注的问题时,这是不适合进入标准库的。举个例子,生成 UUID 的包,或 JWT 包。一些包(包括 web 框架)都是基于标准库构建的。一个很好的具体例子,jmoiron/sqlx 包就是基于 sql/database
包构建的。
Go 和包含一个软件包市场的语言有很大的不同。Node 有 npm,PHP 有 packagist(composer),Ruby 有 gems。事实上 Go 没有官方软件包管理器(一个中央市场),这对于寻找到一个软件包有着重大的影响。有几个软件包管理器可用,例如 gvt,glide 和一个官方的试验品 dep,dep 可能会在将来的某个时间和 Go 语言工具链一起捆绑发布。
dep 是官方的试验品,但还不是官方的工具。查看更多关于 dep 的路线图!
实际上,在官方的 readme 文件中 Glide 建议迁移到 dep。当你开始使用包管理器,建议使用 dep。
Go 代码放在 GitHub,Bitbucket 和其他存储库,甚至可以自行托管。最完整的 Go 语言包列表可以通过搜索 godoc 来找到,godoc 是由这些包生成的文档的中央托管。它不提供类似于上面提到的其他语言项目的软件包市场。有一个值得注意的项目:有点接近其他的软件包管理器,被用作包索引,它是 gopkg.in。
任何你创建的软件包都可能因为代码质量等各种原因而没有被采用。某些程序包作者比其他人更为人所知,如果你正在寻找一些像 flags 配置包那样微不足道的东西,那么你只剩下少量但是高质量的选择。这在相关的包软件系统中是不可能的。
相比之下,Node 的软件包质量急剧下降,因为它的焦点分布在前端和后端之间,所以 Node 中有许多怪癖的代码,这在 Go 中是不存在。Go 是一个完全服务器端的语言,而 Node 往往服务于很多前端的 Javascript 代码。Node 开发中有一些东西,无法用任何逻辑来解释,例如开发和采用 left-pad 和 is-array 包的原因。我无法解释它们为何每周有成百上千万的下载量。
Go 有一个较小的生态系统,但是有很多基于 Go 的项目都被广泛的采用,最近 GitHub 上的 go-chi/chi 有 2500 星星和非常好的评论(和 sqlx 类似,chi 项目是基于底层的 net/http
包构建的)。我们在 ErrorHub 上使用它,我建议你使用它。
有许多 web 框架可用,但是如上所述,你应该首先使用 stdlib,这样你可以在继续前进时明白你真正需要的。使用 web 框架本身是完全没有必要的,但是当你有新的需求时,你可以做出更明智地选择从哪里迁移。
Go 和其他语言之间的不同之处在于语言细节。从 Python 迁移到 Ruby 或从 PHP 迁移到 Javascript 时,你会发现同样的差异。Go 也不例外。你可能会发现(例如切片是如何工作的)起初有点混乱,但从任何语言迁移到任何其他语言时都会遇到这些问题。让我们再看看 ruby 的一个例子 predicate methods。
Go 的入门门槛真的很低。我在 15 年前使用 PHP,迁移到 Go 是相对比较简单的。让你理解 Node 的异步操作是很困难的,包括 Promise 和 yield。如果我能推荐两篇阅读材料,那么你应该阅读一下 the interview with Ryan Dahl, the creator of Node,Bob Nystroms critique of asynchronous functions 也是必读的。
这就是说,我认为 Node 并不是构建大型服务器网站的最佳语言。我会用 Go 的。说实话,这就是我离开 Node 的原因。我意识到:哦,实际上,这不是有史以来最好的服务器端系统。
Ryan Dahl
Go 非常适合为任何您选择驱动您的前端框架的项目提供 API 端点。Websockets?没问题。一群正在互相交谈的 Go 程序?你有没有听说过 Docker 或者 Kubernetes? 这些系统有着令人难以置信的可扩展性,并且是用 Go 写的。
Go 是一门出色的语言,可以提供后端逻辑,例如和数据库交互接口,并通过 HTTP API 端点开放访问。前端技术栈的选择将确保你可以为浏览器使用和呈现此数据。
你被 React 所困恼吗?将其替换为 VueJS 而不用丢弃任何 Go 代码。在其他语言中,你必须严格遵守这个原则来分割应用程序,因为通常情况下,你不是在编写服务器,而只是生成将在浏览器中运行产生输出的脚本。当然,使用 Go 可以以相同的方式使用 html/template
,但是选择使用前端框架实现前端,将会给你带来好处:专注于该框架的开发人员。不是每个人都喜欢 Go。
你不会用 bash 写一个 web 服务器,对不对?
对我来说主要的卖点就是标准库,语言和文档的质量非常高。Ruby,Node,PHP 和其他以 web 开发为中心的语言通常都是单线程的,如果可能的话,超出这个范围的通常都是使用一个附加组件,而不是一等公民。他们的内存管理很差(尽管,至少 PHP 在过去的 15 年里有了很大的改进),也许最重要的是它们都属于脚本语言范畴。编译的代码总是会比通过解释器运行的任何代码都快。
人们总是重新发明轮子,不仅仅是因为他们可以,而且还因为他们可以以某种方式改善它。这可以以很小的增量完成,例如优化一个生成特定输出的特定函数,或者可以以更大的增量完成,例如创建一门将并发性作为一等公民的编程语言。
其他的东西可能不会被处理(这就是为什么在 Go 中有很多关于泛型的争议),但总是有可以改进的空间。我不排除有人会另辟蹊径去提供他们认为最合适的最好的泛型的可能性。人们总是根据他们的经验做出反应。如果你的经验告诉你,并发性是某些 XY 语言的问题,那么你将会找到解决办法。迁移到 Go 是一个很好的方法来解决这个问题。
这篇文章反映了 Go 确实有包管理器,但是到目前为止还没有官方的工具,也没有和 Go 的工具链一起捆绑发布。前面的文章误导了这一点,它暗示了 Go 根本没有包管理器。从技术上讲,所有其他包管理器(至少 npm 和 composer)都是是附加组件。
但如果你能购买一本我的书,那真是太棒了:
我保证如果你买一本书,你会学到更多东西。购买一份拷贝支持我写更多关于类似的话题。谢谢你买我的书。
如果你想预约我的咨询/自由服务时间,请随时给我发电子邮件。 我非常擅长 APIs,Go,Docker,VueJS 和扩展服务等等。
via: https://scene-si.org/2017/10/18/choosing-a-go-framework/
作者:Tit Petric 译者:MDGSF 校对:polaris1119
package main
import "fmt"
func main() {
str := "abcdef"
rstr := reverse(str)
fmt.Println(rstr)
}
func reverse(str string) string {
runes := []rune(str)
l := 0
r := len(runes) - 1
for l <= r {
runes[l], runes[r] = runes[r], runes[l]
l++
r--
}
return string(runes)
}
$ go run test.go
fedcba
package main
import (
"log"
"math/big"
"time"
)
// Duration 测量程序运行时间
func Duration(invocation time.Time, name string) {
elapsed := time.Since(invocation)
log.Printf("%s lasted %s", name, elapsed)
}
func BigIntFactorial(x big.Int) *big.Int {
defer Duration(time.Now(), "IntFactorial")
y := big.NewInt(1)
for one := big.NewInt(1); x.Sign() > 0; x.Sub(&x, one) {
y.Mul(y, &x)
}
return x.Set(y)
}
func main() {
BigIntFactorial(*big.NewInt(10000))
}
https://github.com/tmrts/go-patterns/blob/master/profiling/timing.md