题目描述
输入一个字符串,打印出该字符串中字符的所有排列
例如输入字符串abc,则输出由字符a、b、c 所能排列出来的所有字符串
abc、acb、bac、bca、cab 和 cba
package main
import "fmt"
func CalcAllPermutation(str string) []string {
result := []string{}
core(str, "", &result)
return result
}
func core(remain, cur string, result *[]string) {
if len(remain) == 0 {
*result = append(*result, cur)
return
}
for i, c := range remain {
remain_t := remain[:i] + remain[i+1:]
cur_t := cur + string(c)
core(remain_t, cur_t, result)
}
}
func main() {
result := CalcAllPermutation("abc")
for _, str := range result {
fmt.Println(str)
}
}
类似问题
1、已知字符串里的字符是互不相同的,现在任意组合,比如ab,则输出aa,ab,ba,bb,编程按照字典序输出所有的组合。
关键是提前排序,反复使用素材
设置一个变量表示已输出的个数,然后当个数达到字符串长度时,就输出。
package main
import (
"sort"
"strings"
"fmt"
)
func CalcOrderedPermutation(str string) []string {
// sort input
s := strings.Split(str, "")
sort.Strings(s)
str = strings.Join(s, "")
result := []string{}
core(str, "", len(str), &result)
return result
}
func core(res, cur string, length int, result *[]string) {
if len(cur) == length {
*result = append(*result, cur)
return
}
for _, c := range res {
core(res, cur+string(c), length, result)
}
}
func main() {
result := CalcOrderedPermutation("ab")
for _, str := range result {
fmt.Println(str)
}
}
2、如果不是求字符的所有排列,而是求字符的所有组合,应该怎么办呢?
当输入的字符串中含有相同的字符串时,相同的字符交换位置是不同的排列,但是同一个组合。
举个例子,如果输入abc,它的组合有a、b、c、ab、ac、bc、abc。
分析:去重 -> 排序 -> 1~n 的长度,选择/不选择当前字符,从前向后递归
package main
import (
"strings"
"sort"
"fmt"
)
func CalcAllCombination(str string) []string {
// 使用 map 去重,go 没有 set,尴尬
charSet := make(map[string]int, len(str))
for _, c := range str {
charSet[string(c)] = 1
}
str_t := ""
for k, _ := range charSet {
str_t += k
}
// 排序
s := strings.Split(str_t, "")
sort.Strings(s)
str = strings.Join(s, "")
result := []string{}
// 长度从 1 到 n-1 的组合
for i := 1; i < len(str)+1; i++ {
core(str, "", 0, i, &result)
}
return result
}
func core(str, cur string, begin, length int, result *[]string) {
if len(cur) == length {
*result = append(*result, cur)
return
}
if begin > len(str)-1 {
return
}
core(str, cur+string(str[begin]), begin+1, length, result) // 选取该字符
core(str, cur, begin+1, length, result) // 忽略该字符
}
func main() {
result := CalcAllCombination("bajbc")
for _, str := range result {
fmt.Println(str)
}
}
3、写一个程序,打印出以下的序列。
(a),(b),(c),(d),(e)........(z)
(a,b),(a,c),(a,d),(a,e)......(a,z),(b,c),(b,d).....(b,z),(c,d).....(y,z)
(a,b,c),(a,b,d)....(a,b,z),(a,c,d)....(x,y,z)
....
(a,b,c,d,.....x,y,z)
直接应用上边的组合,稍加改动即可
package main
import (
"strings"
"sort"
"fmt"
)
func CalcAllCombination(str string){
// 使用 map 去重,go 没有 set,尴尬
charSet := make(map[string]int, len(str))
for _, c := range str {
charSet[string(c)] = 1
}
str_t := ""
for k, _ := range charSet {
str_t += k
}
// 排序
s := strings.Split(str_t, "")
sort.Strings(s)
str = strings.Join(s, "")
// 长度从 1 到 n-1 的组合
for i := 1; i < len(str)+1; i++ {
result := []string{}
core(str, "", 0, i, &result)
for j, str_tmp := range result {
if j!= len(result)-1{
fmt.Printf("(%s),",strings.Join(strings.Split(str_tmp,""),","))
}else{
fmt.Printf("(%s)\n",strings.Join(strings.Split(str_tmp,""),","))
}
}
}
}
func core(str, cur string, begin, length int, result *[]string) {
if len(cur) == length {
*result = append(*result, cur)
return
}
if begin > len(str)-1 {
return
}
core(str, cur+string(str[begin]), begin+1, length, result) // 选取该字符
core(str, cur, begin+1, length, result) // 忽略该字符
}
func main() {
CalcAllCombination("abcdefghijklmnopqrstuvwxyz")
}
效率感人,优化再议