全排列(逐步生成结果之迭代空位上添加字符)

1. 问题描述:

 输入一个字符串,输出该字符串的全部全排列集合

 

2. 思路描述:我们先从简单的例子开始考虑:假如输入的字符串为 ABC

我们先考虑A,可以在A的所有空位上添加上当前元素B,可以得到 {BA,AB},对得到的字符串集合再进行添加当前元素那么可以在BA的所有空位上添加元素,得到的集合为{ CBA,BCA,BAC} 在AB的所有空位上添加元素得到的集合为{ CAB,ACB,ABC}

那么就得到了ABC的全部全排列,那么多个字符的处理也是一样的,思路与上面的一样。思路有了,我们需要对上一次得到的集合进行临时的存储,而且需要创建两个list,一个是在初始化的时候创建,另外一个是在for循环里面创建(临时存储的作用),for循环遍历的是原来就已经存在集合,我们需要在遍历的时候往原来的集合中添加元素,然后把添加好元素的集合赋值给原来的下次下一次才可以正确遍历。

其中需要解决的问题是:如何在空位上添加当前元素,在最外层的for循环中表示的是当前需要添加的字符,里面遍历原来的旧的集合,并且在循环中创建一个一个list来保存当前添加新元素的集合,最终把新的集合赋值给旧的集合,遍历之后就需要往空位上添加字符,因为空位上存在多个,所以使用一个for循环,这里使用到了拼接字符串的方法:substring(index)和substring(firstIndex,lastIndex)方法

substring(index)方法可以截取从index到字符串结尾的字符串

substring(firstIndex,lastIndex):截取的字符串为从firstIndex ~ lastIndex - 1索引之间的字符串,所以不包括lastIndex这个字符

当firstIndex = = lastIndex的时候截取字符串的字符串为空

代码中还使用到了对list元素进行排序的方法:Collections.sort(需要排序的list) 去除字符串空格的方法:String对象的replaceAll()方法

 

3. 具体的代码如下:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
public class Main{
	public static void main(String[] args) {
		//在有空的位置上插入元素
		Scanner sc = new Scanner(System.in);
		//去除字符串中的空格:trim()方法去除的是字符串前后的空格 replaceAll()方法是替换所有的空格
		String str = sc.nextLine().replaceAll(" ", "");
		List<String> list = solve(str);
		System.out.println(list.size());
		//对集合中的元素进行排序
		Collections.sort(list);
		for(String strOuput : list){
			System.out.println(strOuput);
		}
		sc.close();
	}

	private static List<String> solve(String str) {
		int n = str.length();
		//System.out.println(str);
		List<String> srcStr = new ArrayList<>();
		if(n == 0){
			return srcStr;
		}
		srcStr.add(str.charAt(0) + "");
		for(int i = 1; i < n; i++){
			//最外层循环是为了添加索引为i的字符串
			List<String> strNew = new ArrayList<>();
			for(String srcStr1 : srcStr){
				for(int j = 0; j <= srcStr1.length(); j++){
					//下面很可能出现数组越界的情况: 特别是strList.charAt(i)的情况下
					//String的subString(firstIndex,lastIndex)方法不包括lastIndex所在位置上的
					//在原来字符串的空位上添加字符: 拼接字符串
					String str1 = srcStr1.substring(0, j) + str.charAt(i) + srcStr1.substring(j);
					strNew.add(str1);
				}
			}
			srcStr = strNew;
		}
		return srcStr;
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值