在Go(Golang)中把缩略语组合的程序

123 阅读2分钟

概述

给出一个字符串数组,编写一个程序,将所有的缩略语组合在一起。

缩略语是指通过重新排列不同的单词或短语的字母而形成的一个单词或短语,通常只使用所有的原始字母一次。例如,anagram这个词本身可以被重新排列成nag a ram二进制这个词也可以被排列成brainy,而adobe这个词可以被排列成abode
例如

Input: ["art", "tap", "rat", "pat", "tar","arm"]
Output: [["art", "rat", "tar"], ["tap", "pat"], ["arm"]]

下面是策略。

  • 复制原始数组。对复制的数组中的每个字符串进行排序。排序后的重复数组将看起来像这样
["art", "apt", "art", "apt", "art", "arm"]
  • 创建一个地图来存储输出
var output map[string][]int
  • 为上述复制的数组建立一个三角形,并对所有字符串进行排序。在插入每个元素后更新上面的地图。对于 "art "来说,地图应该如下所示,因为art在原数组中的0、2和5的位置有它的变形符号。
map["art"] = [0,2,4]
  • 遍历地图,通过在输入的字符串数组中建立索引来打印输出。

程序

以下是相同的程序

package main

import (
	"fmt"
	"sort"
)

func main() {
	strs := []string{"art", "tap", "rat", "pat", "tar", "arm"}
	output := groupAnagrams(strs)
	fmt.Println(output)

	strs = []string{""}
	output = groupAnagrams(strs)
	fmt.Println(output)

	strs = []string{"a"}
	output = groupAnagrams(strs)
	fmt.Println(output)
}

type sortRune []rune

func (s sortRune) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}

func (s sortRune) Less(i, j int) bool {
	return s[i] < s[j]
}

func (s sortRune) Len() int {
	return len(s)
}

func groupAnagrams(strs []string) [][]string {

	anagramMap := make(map[string][]int)
	var anagrams [][]string
	trie := &trie{root: &trieNode{}}

	lenStrs := len(strs)

	var strsDup []string

	for i := 0; i < lenStrs; i++ {
		runeCurrent := []rune(strs[i])
		sort.Sort(sortRune(runeCurrent))
		strsDup = append(strsDup, string(runeCurrent))
	}

	for i := 0; i < lenStrs; i++ {
		anagramMap = trie.insert(strsDup[i], i, anagramMap)
	}

	for _, value := range anagramMap {
		var combinedTemp []string
		for i := 0; i < len(value); i++ {
			combinedTemp = append(combinedTemp, strs[value[i]])
		}
		anagrams = append(anagrams, combinedTemp)
	}

	return anagrams
}

type trieNode struct {
	isWord    bool
	childrens [26]*trieNode
}

type trie struct {
	root *trieNode
}

func (t *trie) insert(input string, wordIndex int, anagramMap map[string][]int) map[string][]int {
	inputLen := len(input)
	current := t.root

	for i := 0; i < inputLen; i++ {
		index := input[i] - 'a'
		if current.childrens[index] == nil {
			current.childrens[index] = &trieNode{}
		}
		current = current.childrens[index]
	}
	current.isWord = true
	if anagramMap[input] == nil {
		anagramMap[input] = []int{wordIndex}
	} else {
		anagramMap[input] = append(anagramMap[input], wordIndex)
	}
	return anagramMap
}

输出

[[art rat tar] [tap pat] [arm]]
[[]]
[[a]]