分割版本字符串直到找到为止

huangapple go评论93阅读模式
英文:

splitting version string until found

问题

在这个问题中,你想要实现以下输出:

Version 3.14.15.5.123.2 is called: apple
Version 3.14.15.13.123 is called: orange
Version 3.14.15.19.12 is called: pear

你在考虑使用字符串搜索、切片、搜索、切片循环的方式来找到匹配的结果。你想知道是否有更简单的方法。

以下是一个可能的解决方案:

package main

import (
	"fmt"
)

type apps []app

type app struct {
	version string
}

type releases []release

type release struct {
	name     string
	platform string
}

func main() {

	var versions releases
	versions = append(versions, release{name: "apple", platform: "3.14.15"})
	versions = append(versions, release{name: "orange", platform: "3.14.15.13"})
	versions = append(versions, release{name: "pear", platform: "3.14.19"})

	var test apps
	test = append(test, app{version: "3.14.15.5.123.2"}) // should map to apple
	test = append(test, app{version: "3.14.15.13.123"})  // should map to orange
	test = append(test, app{version: "3.14.15.19.12"})   // should map to pear

	for _, r := range test {
		for _, v := range versions {
			if v.platform == r.version {
				fmt.Printf("Version %s is called: %s\n", r.version, v.name)
				break
			}
		}
	}

}

这段代码使用了两个结构体类型:appreleaseapp 结构体表示应用程序的版本,release 结构体表示发布的版本。我们首先定义了一个 versions 切片,其中包含了所有的发布版本。然后,我们定义了一个 test 切片,其中包含了要测试的应用程序版本。

接下来,我们使用嵌套的循环来比较每个测试版本和发布版本,如果找到匹配的版本,就输出对应的应用程序名称。

希望这可以帮助到你!

英文:

Sort of went down the rabbit hole on this one:

package main

import (
	"fmt"
)

type apps []app

type app struct {
	version string
}

type releases []release

type release struct {
	name     string
	platform string
}

func main() {

	var versions releases
	versions = append(versions, release{name: "apple", platform: "3.14.15"})
	versions = append(versions, release{name: "orange", platform: "3.14.15.13"})
	versions = append(versions, release{name: "pear", platform: "3.14.19"})

	var test apps
	test = append(test, app{version: "3.14.15.5.123.2"}) // should map to apple
	test = append(test, app{version: "3.14.15.13.123"})  // should map to orange
	test = append(test, app{version: "3.14.15.19.12"})   // should map to pear

	for _, r := range test {
		fmt.Printf("Version %s is called: %s\n", r.version, "?")
	}

}


I'm trying to achieve the following output:

Version 3.14.15.5.123.2 is called: apple
Version 3.14.15.13.123 is called: orange
Version 3.14.15.19.12 is called: pear

I was thinking some sort of string search, slice, search, slice loop until i could find a match? is there an easier way?

答案1

得分: 3

你需要找到发布类型中最长的前缀。为此,你可以实现一个类似下面这样的函数:

package main

import (
	"fmt"
	"strings"
)

type apps []app

type app struct {
	version string
}

type releases []release

type release struct {
	name     string
	platform string
}

func (r releases) FindName(version string) string {
	result := ""
	max := 0
	for _, release := range r {
		if strings.HasPrefix(version, release.platform) {
			if max < len(release.platform) {
				max = len(release.platform)
				result = release.name
			}
		}
	}
	return result
}

func main() {

	var versions releases
	versions = append(versions, release{name: "apple", platform: "3.14.15"})
	versions = append(versions, release{name: "orange", platform: "3.14.15.13"})
	versions = append(versions, release{name: "pear", platform: "3.14.19"})

	var test apps
	test = append(test, app{version: "3.14.15.5.123.2"}) // 应该映射到 apple
	test = append(test, app{version: "3.14.15.13.123"})  // 应该映射到 orange
	test = append(test, app{version: "3.14.19.12"})      // 应该映射到 pear

	for _, r := range test {
		fmt.Printf("版本 %s 被称为:%s\n", r.version, versions.FindName(r.version))
	}

}
英文:

You have to find the longest prefix in the releases type. For this you can implement a func like this one:

package main

import (
	&quot;fmt&quot;
	&quot;strings&quot;
)

type apps []app

type app struct {
	version string
}

type releases []release

type release struct {
	name     string
	platform string
}

func (r releases) FindName(version string) string {
	result := &quot;&quot;
	max := 0
	for _, release := range r {
		if strings.HasPrefix(version, release.platform) {
			if max &lt; len(release.platform) {
				max = len(release.platform)
				result = release.name
			}
		}
	}
	return result
}

func main() {

	var versions releases
	versions = append(versions, release{name: &quot;apple&quot;, platform: &quot;3.14.15&quot;})
	versions = append(versions, release{name: &quot;orange&quot;, platform: &quot;3.14.15.13&quot;})
	versions = append(versions, release{name: &quot;pear&quot;, platform: &quot;3.14.19&quot;})

	var test apps
	test = append(test, app{version: &quot;3.14.15.5.123.2&quot;}) // should map to apple
	test = append(test, app{version: &quot;3.14.15.13.123&quot;})  // should map to orange
	test = append(test, app{version: &quot;3.14.19.12&quot;})      // should map to pear

	for _, r := range test {
		fmt.Printf(&quot;Version %s is called: %s\n&quot;, r.version, versions.FindName(r.version))
	}

}

答案2

得分: 1

如果你需要进行多次查找,那么你可以构建一个索引并在其中进行搜索。这样,搜索的最大时间复杂度将是 O(n),其中 n 是你要搜索的版本号的长度。

package main

import (
	"fmt"
	"sort"
	"strings"
)

type apps []app

type app struct {
	version string
}

type releases []release

type release struct {
	name     string
	platform string
}

var index map[string]string

func BuildIndex(r releases) {
	sort.Slice(r, func(i, j int) bool { return r[i].platform < r[j].platform })
	index = make(map[string]string)
	for _, release := range r {
		s := ""
		for _, rn := range release.platform {
			s += string(rn)
			if strings.HasSuffix(s, ".") {
				continue
			}
			if _, found := index[s]; !found {
				index[s] = release.name
			}
		}
	}
}

func FindInIndex(v string) string {
	for {
		if name, found := index[v]; found {
			return name
		}
		v = v[:len(v)-1]
		if v == "" {
			break
		}
	}
	return ""
}

func main() {
	var versions releases
	versions = append(versions, release{name: "apple", platform: "3.14.15"})
	versions = append(versions, release{name: "orange", platform: "3.14.15.13"})
	versions = append(versions, release{name: "pear", platform: "3.14.19"})

	BuildIndex(versions)

	var test apps
	test = append(test, app{version: "3.14.15.5.123.2"}) // should map to apple
	test = append(test, app{version: "3.14.15.13.123"})  // should map to orange
	test = append(test, app{version: "3.14.19.12"})      // should map to pear

	for _, r := range test {
		fmt.Printf("Version %s is called: %s\n", r.version, FindInIndex(r.version))
	}

}

以上是要翻译的代码部分。

英文:

If you need to make so many lookups, then you can build an index and search in it. This way a search would take optimally maximum O(n) where n is the length of the version you are searching.

package main
import (
&quot;fmt&quot;
&quot;sort&quot;
&quot;strings&quot;
)
type apps []app
type app struct {
version string
}
type releases []release
type release struct {
name     string
platform string
}
var index map[string]string
func BuildIndex(r releases) {
sort.Slice(r, func(i, j int) bool { return r[i].platform &lt; r[j].platform })
index = make(map[string]string)
for _, release := range r {
s := &quot;&quot;
for _, rn := range release.platform {
s += string(rn)
if strings.HasSuffix(s, &quot;.&quot;) {
continue
}
if _, found := index
展开收缩
; !found { index
展开收缩
= release.name } } } } func FindInIndex(v string) string { for { if name, found := index[v]; found { return name } v = v[:len(v)-1] if v == &quot;&quot; { break } } return &quot;&quot; } func main() { var versions releases versions = append(versions, release{name: &quot;apple&quot;, platform: &quot;3.14.15&quot;}) versions = append(versions, release{name: &quot;orange&quot;, platform: &quot;3.14.15.13&quot;}) versions = append(versions, release{name: &quot;pear&quot;, platform: &quot;3.14.19&quot;}) BuildIndex(versions) var test apps test = append(test, app{version: &quot;3.14.15.5.123.2&quot;}) // should map to apple test = append(test, app{version: &quot;3.14.15.13.123&quot;}) // should map to orange test = append(test, app{version: &quot;3.14.19.12&quot;}) // should map to pear for _, r := range test { fmt.Printf(&quot;Version %s is called: %s\n&quot;, r.version, FindInIndex(r.version)) } }

huangapple
  • 本文由 发表于 2021年9月3日 04:06:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/69036439.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定