字符串的全排列

题目描述

输入一个字符串,打印出该字符串中字符的所有排列

例如输入字符串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")
}

       效率感人,优化再议

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值