I am trying to find if an element exists in my linked list so that duplicate elements are not added.
My code follows playground:
package main
import "fmt"
func (e Ensemble) EstVide() bool {
return e.ensemble == nil
}
func (e Ensemble) Card() int {
return e.longueur
}
type Cellule struct {
elem int
suivant *Cellule
}
type Ensemble struct {
ensemble *Cellule
longueur int
}
func (c Cellule) String() string {
if c.suivant == nil {
return fmt.Sprintf("%v}", c.elem)
}
return fmt.Sprintf("%v", c.elem)
}
func (e Ensemble) String() string {
if e.EstVide() {
return ""
}
res := "{"
for curr := e.ensemble; curr != nil; curr = curr.suivant {
res += fmt.Sprintf("%s ", curr)
}
return res[:len(res)-1]
}
func (e Ensemble) Appartient(valeur int) bool {
body := e.String()
for i := 0; i < e.Card(); i++ {
if valeur == int(body[i]) {
return true
}
}
return false
}
func (e *Ensemble) Ajouter(valeur int) {
if !e.Appartient(valeur) {
e.ensemble = &Cellule{elem: valeur, suivant: e.ensemble}
e.longueur++
}
}
func main() {
monEns := Ensemble{}
fmt.Printf("Nb d'éléments dans monEns %v\n", monEns.Card())
fmt.Printf("monEns = %v\n", monEns)
monEns.Ajouter(42)
monEns.Ajouter(10)
monEns.Ajouter(20)
monEns.Ajouter(10)
fmt.Printf("Nb d'éléments dans monEns %v\n", monEns.Card())
fmt.Printf("monEns = %v \n", monEns)
}
The output ({10 20 10 42} includes a duplicate element (10). How can I prevent this?
Related
I'm struggling with updating a slice inside map rulesByCountry without any success.
The value of enabled changes only inside the function UpdateName but the map itself still sees this value unchanged. I assume it's something to do with pointers. I guess I did not grasp the concept of it. Can someone direct me what I'm doing wrong here? I tried a lot of things and run out of options. I would appreciate any kind of help.
import (
"fmt"
)
// Consts
const RuleSeparateStreetNameFromHome string = "Separate street number from home"
// Types
type Address struct {
AddressLines []string
Country string
}
type RuleChain []RuleDefinition
type RuleDefinition struct {
Name string
Enabled bool
}
//Map
var rulesByCountry map[string][]RuleDefinition = map[string][]RuleDefinition{
"DE": {
{
Name: RuleSeparateStreetNameFromHome,
// TODO some logic,
Enabled: false,
},
},
}
func main() {
var addr *Address
addr = &Address{
AddressLines: []string{
"Street3",
},
Country: "DE",
}
rules := GetRulesForCountry(addr.GetCountry())
rules.UpdateName(RuleSeparateStreetNameFromHome)
fmt.Println(rules)
}
func GetRulesForCountry(country string) RuleChain {
if rules, ok := rulesByCountry[country]; ok {
return rules
}
return nil
}
func (a *Address) GetFirstAddressLine() string {
return a.GetAddressLine(1)
}
func (a *Address) GetAddressLine(lineNumber int) string {
if lineNumber <= 0 {
return ""
}
lines := a.GetAddressLines()
if len(lines) >= lineNumber {
return lines[lineNumber-1]
}
return ""
}
func (m *Address) GetAddressLines() []string {
if m != nil {
return m.AddressLines
}
return nil
}
func (r *RuleChain) UpdateName(name string) {
for _, rule := range *r {
if rule.Name == name {
rule.Enabled = true
fmt.Print(rule)
}
}
}
func (m *Address) GetCountry() string {
if m != nil {
return m.Country
}
return ""
}
Based on the inputs of mkopriva
package main
import (
"fmt"
)
// Consts
const RuleSeparateStreetNameFromHome string = "Separate street number from home"
// Types
type Address struct {
AddressLines []string
Country string
}
type RuleChain []*RuleDefinition
type RuleDefinition struct {
Name string
Enabled bool
}
//Map
var rulesByCountry map[string][]*RuleDefinition = map[string][]*RuleDefinition{
"DE": {
{
Name: RuleSeparateStreetNameFromHome,
// TODO some logic,
Enabled: false,
},
},
}
func main() {
var addr *Address
addr = &Address{
AddressLines: []string{
"Street3",
},
Country: "DE",
}
rules := GetRulesForCountry(addr.GetCountry())
rules.UpdateName(RuleSeparateStreetNameFromHome)
fmt.Println(rules[0])
}
func GetRulesForCountry(country string) RuleChain {
if rules, ok := rulesByCountry[country]; ok {
return rules
}
return nil
}
func (a *Address) GetFirstAddressLine() string {
return a.GetAddressLine(1)
}
func (a *Address) GetAddressLine(lineNumber int) string {
if lineNumber <= 0 {
return ""
}
lines := a.GetAddressLines()
if len(lines) >= lineNumber {
return lines[lineNumber-1]
}
return ""
}
func (m *Address) GetAddressLines() []string {
if m != nil {
return m.AddressLines
}
return nil
}
func (r *RuleChain) UpdateName(name string) {
for _, rule := range *r {
if rule.Name == name {
rule.Enabled = true
fmt.Print(rule)
}
}
}
func (m *Address) GetCountry() string {
if m != nil {
return m.Country
}
return ""
}
Output:
&{Separate street number from home true}&{Separate street number from home true}
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.
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
I am trying to create a generic Binary Tree in Golang. How can I compare data from an interface and input data in the code? Here is an example of what I am trying to do. The comparison that is giving me trouble is this
} else if cur.data < data {
-
package DSAA
type TreeNode struct {
data interface{}
right *TreeNode
left *TreeNode
}
type BinarySearchTree struct {
root *TreeNode
}
func BSTCreate() *BinarySearchTree {
return &BinarySearchTree{nil}
}
func (b *BinarySearchTree) Insert(cur TreeNode, data interface{}) *BinarySearchTree {
if &cur == nil {
cur := &TreeNode{data, nil, nil}
} else if cur.data < data {
b = b.Insert(*cur.left, data)
} else {
b = b.Insert(*cur.right, data)
}
return b
}
You have some options:
1- Using runtime type switch:
package main
import (
"fmt"
)
func main() {
fmt.Println(Less(1, 2)) // true
fmt.Println(Less("AB", "AC")) // true
}
func Less(a, b interface{}) bool {
switch v := a.(type) {
case int:
w := b.(int)
return v < w
case string:
w := b.(string)
return v < w
}
return false
}
then replace } else if cur.data < data { with
} else if Less(cur.data , data) {
2- Using Comparer interface:
package main
import (
"fmt"
)
type Comparer interface {
// Less reports whether the element is less than b
Less(b interface{}) bool
}
func main() {
a, b := Int(1), Int(2)
fmt.Println(a.Less(b)) // true
c, d := St("A"), St("B")
fmt.Println(c.Less(d)) // true
}
type Int int
func (t Int) Less(b interface{}) bool {
if v, ok := b.(Int); ok {
return int(t) < int(v)
}
return false
}
type St string
func (t St) Less(b interface{}) bool {
if v, ok := b.(St); ok {
return string(t) < string(v)
}
return false
}
3- Using reflect
I was wondering if this is the way to create and pass 'generic'(yeah I know, a sensitive word in GoLang) lists to a FindAll function.
Here's my attempt:
package main
import (
"container/list"
"fmt"
"strings"
)
func FindAll(lst *list.List, p func(interface{}) bool) *list.List {
ans := list.New()
for i := lst.Front(); i != nil; i = i.Next() {
if p(i.Value) {
ans.PushBack(i.Value)
}
}
return ans
}
func ConvertToInt(p func(int) bool) func(interface{}) bool {
return func(v interface{}) bool {
if value, ok := v.(int); ok {
if p(value) {
return true
} else {
return false
}
} else {
return false
}
}
}
func IsEven(n int) bool {
if n%2 == 0 {
return true
}
return false
}
func ConvertoString(p func(s string) bool) func(interface{}) bool {
return func(v interface{}) bool {
if value, ok := v.(string); ok {
if p(value) {
return true
} else {
return false
}
} else {
return false
}
}
}
func IsHello(str string) bool {
if strings.ToLower(str) == "hello" {
return true
} else {
return false
}
}
func main() {
fmt.Println("Find All Programs!\n\n")
lsti := list.New()
for i := 0; i < 11; i++ {
lsti.PushBack(i)
}
ansIsEven := FindAll(lsti, ConvertToInt(IsEven))
for i := ansIsEven.Front(); i != nil; i = i.Next() {
if value, ok := i.Value.(int); ok {
fmt.Printf("Found even: %d\n", value)
} else {
fmt.Println("Huh! What's that?")
}
}
}
I've been playing with this for a while and thought I'd better get the advice of the Go experts before I convince myself its correct.
The code as-is is pretty fine, but you should ask your self 2 questions:
1. Why shouldn't you use a typed slice? (interface{} performance is slow compared to the explicit type, although it will greatly improve in Go 1.7)
2. Would it be better to implement your specific type as a linked list?
Something like this can be much more efficient:
type IntList []int
func (l IntList) Filter(fn func(v int) bool) IntList {
var o IntList
for _, v := range l {
if fn(v) {
o = append(o, v)
}
}
return o
}
There's almost always a better alternative to container/list, however it all depends on your use case.
The strings.Join function takes slices of strings only:
s := []string{"foo", "bar", "baz"}
fmt.Println(strings.Join(s, ", "))
But it would be nice to be able to pass arbitrary objects which implement a ToString() function.
type ToStringConverter interface {
ToString() string
}
Is there something like this in Go or do I have to decorate existing types like int with ToString methods and write a wrapper around strings.Join?
func Join(a []ToStringConverter, sep string) string
Attach a String() string method to any named type and enjoy any custom "ToString" functionality:
package main
import "fmt"
type bin int
func (b bin) String() string {
return fmt.Sprintf("%b", b)
}
func main() {
fmt.Println(bin(42))
}
Playground: http://play.golang.org/p/Azql7_pDAA
Output
101010
When you have own struct, you could have own convert-to-string function.
package main
import (
"fmt"
)
type Color struct {
Red int `json:"red"`
Green int `json:"green"`
Blue int `json:"blue"`
}
func (c Color) String() string {
return fmt.Sprintf("[%d, %d, %d]", c.Red, c.Green, c.Blue)
}
func main() {
c := Color{Red: 123, Green: 11, Blue: 34}
fmt.Println(c) //[123, 11, 34]
}
Another example with a struct :
package types
import "fmt"
type MyType struct {
Id int
Name string
}
func (t MyType) String() string {
return fmt.Sprintf(
"[%d : %s]",
t.Id,
t.Name)
}
Be careful when using it,
concatenation with '+' doesn't compile :
t := types.MyType{ 12, "Blabla" }
fmt.Println(t) // OK
fmt.Printf("t : %s \n", t) // OK
//fmt.Println("t : " + t) // Compiler error !!!
fmt.Println("t : " + t.String()) // OK if calling the function explicitly
This works well
package main
import "fmt"
type Person struct {
fname, sname string
address string
}
func (p *Person) String() string {
s:= fmt.Sprintf("\n %s %s lives at %s \n", p.fname, p.sname, p.address)
return s
}
func main(){
alex := &Person{"Alex", "Smith", "33 McArthur Bvd"}
fmt.Println(alex)
}
Output:
Alex Smith lives at 33 McArthur Bvd
If you have a fixed set of possible types for elements that could be converted, then you can define conversion functions for each, and a general conversion function that uses reflection to test the actual type of an element and call the relevant function for that element, eg:
func ToStringint(x int) string {
return strconv.Itoa(x)
}
func ToStringlong(x int64) string {
return strconv.FormatInt(x,10)
}
func ToStringdouble(x float64) string {
return fmt.Sprintf("%f", x)
}
func ToStringboolean(x bool) string {
if x {
return "true"
}
return "false"
}
func ToStringOclAny(x interface{}) string {
if reflect.TypeOf(x) == TYPEint {
return strconv.Itoa(x.(int))
}
if reflect.TypeOf(x) == TYPEdouble {
return fmt.Sprintf("%f", x.(float64))
}
if reflect.TypeOf(x) == TYPElong {
return strconv.FormatInt(x.(int64),10)
}
if reflect.TypeOf(x) == TYPEString {
return x.(string)
}
if reflect.TypeOf(x) == TYPEboolean {
return ToStringboolean(x.(bool))
}
if reflect.TypeOf(x) == TYPESequence {
return ToStringSequence(x.(*list.List))
}
if reflect.TypeOf(x) == TYPEMap {
return ToStringMap(x.(map[interface{}]interface{}))
}
return ""
}
func ToStringSequence(col *list.List) string {
res := "Sequence{"
for e := col.Front(); e != nil; e = e.Next() {
res = res + ToStringOclAny(e.Value)
if e.Next() != nil {
res = res + ", "
}
}
return res + "}"
}
func ToStringSet(col *list.List) string {
res := "Set{"
for e := col.Front(); e != nil; e = e.Next() {
res = res + ToStringOclAny(e.Value)
if e.Next() != nil {
res = res + ", "
}
}
return res + "}"
}
func ToStringMap(m map[interface{}]interface{}) string {
res := "Map{"
for i, v := range m {
res = res + ToStringOclAny(i) + " |-> " + ToStringOclAny(v) + " "
}
return res + "}"
}
Here is a simple way to handle this:
package main
import (
"fat"
"strconv"
)
type Person struct {
firstName, lastName string
age int
}
func (p Person) GetFullName() string {
return p.firstName + " " + p.lastName
}
func (p Person) GetAge() int {
return p.age
}
func (p Person) GetAgeAsString() string {
return strconv.Itoa(p.age)
}
func main() {
p := Person {"John", "Doe", 21}
fmt.Println(p.GetFullName())
fmt.Println(p.GetAgeAsString())
}
Output:
"John Doe"
"21"
I prefer something like the following:
type StringRef []byte
func (s StringRef) String() string {
return string(s[:])
}
…
// rather silly example, but ...
fmt.Printf("foo=%s\n",StringRef("bar"))