Skip to content

Instantly share code, notes, and snippets.

@serialhex
Created July 2, 2011 18:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save serialhex/1061466 to your computer and use it in GitHub Desktop.
Save serialhex/1061466 to your computer and use it in GitHub Desktop.
/* ok, heres what i'm trying to do...
* i'm trying to group all the words of equal length together,
* and then group them all by the first letter they start with
* so i can do something like:
* - for all five-letter d-words
* foo := words[5]["d"]
* i know my nested structures are kind of wonky, but i'm not sure how else to represent it...
* any help is welcome!
*/
// this works with the awesomeness!!!
func wordSort(dict []string) (map[int] map[uint8] []string) {
words := make(map[int] map[uint8] []string)
for _, str := range dict {
if words[len(str)] == nil {
words[len(str)] = make(map[uint8] []string)
}
words[len(str)][str[0]] = append(words[len(str)][str[0]], str)
}
return words
}
Copy link

ghost commented Jul 2, 2011

Here are two versions of the same deal. First one is the same map approach you use. The second one uses slices of integers. First level holds string length's. Second level holds the first character. The last level holds an index into the dict slice instead of the actual word.

The slice version is consistently 4 times faster than the map version. I am not entirely sure about the memory usage though, because the slice version creates a lot of empty array slots.

func sortMap(dict []string) (m map[int] map[byte] []string) {
    var i, l int
    var c byte
    var ok bool

    m = make(map[int] map[byte] []string)
    for i = range dict {
        if l = len(dict[i]); l == 0 {
            continue
        }

        if _, ok = m[l]; !ok {
            m[l] = make(map[byte] []string)
        }

        c = dict[i][0]
        m[l][c] = append(m[l][c], dict[i])
    }

    return
}

func sortSlice(dict []string) (m [][][]int) {
    var i, l int
    var c byte

    for i = range dict {
        if l = len(dict[i]); l == 0 {
            continue
        }

        if len(m) <= l {
            t := make([][][]int, l+1)
            copy(t, m)
            m = t
        }

        c = dict[i][0]
        if len(m[l]) <= int(c) {
            t := make([][]int, c+1)
            copy(t, m[l])
            m[l] = t
        }

        m[l][c] = append(m[l][c], i)
    }

    return
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment