需求
今天工作了大半个下午,想随便写点代码放松下调整个状态,然后就想到了N年前的一道面试题(很遗憾当年没有做出来,导致自己的笔试被鄙视了),写个java方法实现针对原始长度为N的字符串,使用0-N个*代替原始字母后的所有结果,举个栗子:给定字符串为ABC,则需要输出ABC,AB*,A*C,A**,*BC,*B*,**C,***(结果应该是2的N次方个)。没多想就它了,哪里跌倒哪里爬起来
实现逻辑
从题面分析就是给定条件输出各种组合,回到这道题,其实更形象的描述应该是二进制加法,想象一下像不像?000,001,010,011,100,101,110,111(当初怎么没有这个灵感....),既然想明白了就开始撸代码吧,废话不说,直接上代码
public class Test {
public static void main(String[] args) {
List<String> list = Arrays.asList(new String[]{"A", "B", "C", "D"});
printStarComposition(list);
}
private static void printStarComposition(List<String> list) {
int[] array = new int[list.size()];
StringBuffer sb = new StringBuffer();
while (true) {
//1打印*,0打印原始值
for (int i = 0; i < array.length; i++) {
if (array[i] == 1) {
sb.append("*");
} else {
sb.append(list.get(i));
}
}
//打印拼接字符串
System.out.println(sb.toString());
//对象重用,删除当前值
sb.delete(0, sb.length());
//标识是否需要执行加法,每轮执行一次
boolean needAdd = true;
//核心算法类似二进制加法,就是反向遍历整形数组,如果遇到1,则将1变成0,遇到第一个0,变成1,然后跳出for循环
for (int i = array.length - 1; i >= 0; i--) {
if (array[i] == 0) {
array[i]++;
needAdd = false;
break;
} else {
array[i] = 0;
}
}
//如果循环退出后needAdd仍旧是true,说明未遇到0,数组中都是1,说明打印完毕,跳出死循环,打印结束
if (needAdd) {
break;
}
}
}
}
执行结果如下:
ABCD
ABC*
AB*D
AB**
A*CD
A*C*
A**D
A***
*BCD
*BC*
*B*D
*B**
**CD
**C*
***D
****
结语
条条大路通罗马,编程也是,差的就是这条路的远近(执行效率以及代码质量),但是找到近路的前提是先要找到路。当初我就没有找到路,结果连罗马长什么样子都不知道....不过塞翁失马焉知非福,如果当初真的到了罗马,现在的我会是什么样子,一切未知。但是有一点可知的是,如果你是技术人员或者曾经是技术人员,任何时候都不要放弃技术,这是一个技术人员安身立命的本钱,如果你还在软件圈哪怕你转行,技术也会成为你一个非对称打击的优势点,能成为你剩余职业生涯中的一把利器。技术好比你的肌肉,哪怕你已经不去健身房了,仍需要时不时的锻炼来维护肌肉状态,这样肌肉才不会变成五花肉,技术亦是如此