英文:
Merging Intervals out of hyphenated string ranges
问题
我有一个这样的字符串:
ports := []string{"1", "2-7", "12-1200", "10-500"}
我想将其转换为整数集合,输出应该是:
[]intSet{1, 2-7, 10-1200}
其中intSet是某种整数集合,我可以轻松地添加和删除元素。
更新1
intSet是一个sets列表。
所以,2-7也是一个集合。
更新2
这里最大的集合被合并。
例如:
- "1" -> 1
 - "2-7" -> 2-7
 - "12-1200" 和 "10-500" => "10..12.....500....1200" -> 10-1200
 
由于它是一个set,因此它包含了一个唯一的范围,该范围覆盖整个集合。
英文:
I have a string like this:
ports := []string{"1", "2-7", "12-1200", "10-500"}
I would like to make an integer set out of this like the output should be :
[]intSet{ 1, 2-7, 10-1200 }
Where intSet is some kind of integer set from which I am able to easily remove and add elements.
Update 1
intSet is a list of sets.
So, 2-7 is also a set.
Update 2
Here the largest set is merged.
e.g.
- "1" -> 1
 - "2-7" -> 2-7
 - "12-1200" & "10-500" => "10..12.....500....1200" -> 10-1200
 
Since it's a set so it encompasses a unique range for this, a range which covers the whole set.
答案1
得分: 2
package main
import (
	"fmt"
	"log"
	"strconv"
	"strings"
)
type intSet struct {
	start int
	end   int
}
func (s intSet) String() string {
	if s.start == s.end {
		return fmt.Sprintf("%d", s.start)
	}
	return fmt.Sprintf("%d-%d", s.start, s.end)
}
func (s intSet) in(i int) bool {
	return s.start <= i && i <= s.end
}
func (s *intSet) union(set intSet) {
	if set.start < s.start {
		s.start = set.start
	}
	if set.end > s.end {
		s.end = set.end
	}
}
func insert(set intSet, is []intSet) bool {
	for i, s := range is {
		if s.in(set.start) || s.in(set.end) {
			is[i].union(set)
			return true
		}
		//updated here with thankful to @mh-cbon
		if set.in(s.start) || set.in(s.end) {
			is[i].union(set)
			return true
		}
	}
	return false
}
func main() {
	var set []intSet
	ports := []string{"1", "2-7", "12-1200", "10-500", "9-5500"}
	for _, port := range ports {
		s := strings.Split(port, "-")
		if len(s) < 1 || len(s) > 2 {
			log.Fatalln("set不能有多个值或没有值")
		}
		start, err := strconv.Atoi(s[0])
		if err != nil {
			log.Fatalln(err)
		}
		end := start
		if len(s) == 2 {
			end, err = strconv.Atoi(s[1])
			if err != nil {
				log.Fatalln(err)
			}
		}
		temSet := intSet{
			start: start,
			end:   end,
		}
		if !insert(temSet, set) {
			set = append(set, temSet)
		}
	}
	fmt.Println(set) //[1 2-7 9-5500]
}
在这里运行
英文:
package main
import (
"fmt"
"log"
"strconv"
"strings"
)
type intSet struct {
start int
end   int
}
func (s intSet) String() string {
if s.start == s.end {
return fmt.Sprintf("%d", s.start)
}
return fmt.Sprintf("%d-%d", s.start, s.end)
}
func (s intSet) in(i int) bool {
return s.start <= i && i <= s.end
}
func (s *intSet) union(set intSet) {
if set.start < s.start {
s.start = set.start
}
if set.end > s.end {
s.end = set.end
}
}
func insert(set intSet, is []intSet) bool {
for i, s := range is {
if s.in(set.start) || s.in(set.end) {
is[i].union(set)
return true
}
//updated here with thankful to @mh-cbon
if set.in(s.start) || set.in(s.end) {
is[i].union(set)
return true
}
}
return false
}
func main() {
var set []intSet
ports := []string{"1", "2-7", "12-1200", "10-500", "9-5500"}
for _, port := range ports {
s := strings.Split(port, `-`)
if len(s) < 1 || len(s) > 2 {
log.Fatalln(`set cannot have multiple values or no value`)
}
start, err := strconv.Atoi(s[0])
if err != nil {
log.Fatalln(err)
}
end := start
if len(s) == 2 {
end, err = strconv.Atoi(s[1])
if err != nil {
log.Fatalln(err)
}
}
temSet := intSet{
start: start,
end:   end,
}
if !insert(temSet, set) {
set = append(set, temSet)
}
}
fmt.Println(set) //[1 2-7 9-5500]
}
run here
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论