在没有电话的时代,摩尔斯电码是无线电传输领域中的一种常用代码。电码以短信号(短点,o)和长信号(长点,-)的不同组合表示各种文字。
例如:o—表示英文字母J,而—表示英文字母M。
假设有一本以n个长点和m(n、m<=100)个短点组成的、包含所有信号的字典。例如:n=m=2,就会包含如下信号。
–oo
-o-o
-oo-
o–o
o-o-
oo–
Java暴力破解
public class demo05 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("请输入长点、短点和第N个信号,请用逗号分割:");
String line = in.nextLine();
int n = Integer.parseInt(line.split(",")[0]);
int m = Integer.parseInt(line.split(",")[1]);
int s = Integer.parseInt(line.split(",")[2]);
in.close();
List<String> list = func(n, m);
System.out.println("第" + s + "个信号为:");
System.out.println(list.get(s - 1));
}
public static String getString(int[] chs) {
StringBuffer str = new StringBuffer();
for (int i : chs) {
str.append(i == 1 ? '-' : 'o');
}
System.out.println(str);
return str.toString();
}
public static List<String> func(int n, int m) {
List<String> results = new ArrayList<String>(); // 存储已经排列好的数
int[] chs = new int[n + m];
for (int i = 0; i < n; i++) {// 给摩尔斯电码赋初值
chs[i] = 1; // 长点用1表示
}
results.add(getString(chs)); // 第一次拼接摩尔斯电码也加入结果集
int r = 0; // 记录右边的长点数量 用于控制内部长点移动次数
// 根据长点数量控制外层循环次数
for (int i = n - 1; i >= 0; i--) {
int j = i; // j 记录当前移动的长点位置
while (r == 0 && j < chs.length - 1) { // 当r等于0时 表示左边还没有长点,可以直接将最右边的长点移动到尾
// 此while循环只可能执行一次
chs[j] = 1 - chs[j];
chs[j + 1] = 1 - chs[j + 1];
j++;
results.add(getString(chs));
}
if (r > 0 && j + 1 < chs.length) { // 当右边的长点数量大于0且j+1不超过数量长度
// 先将排列在第n-1的长点j位置移动到j+1的位置
chs[j] = 1 - chs[j];
chs[j + 1] = 1 - chs[j + 1];
j++;
for (int k = 0; k < r; k++) { // 此for循环的作用是 将最后的几个长点移动到当前的长点后
// 采用双指针 调换当前长点后一个和尾的位置
chs[j + 1 + k] = 1 - chs[j + 1 + k]; // 以此类推 010011 011010 011100
chs[n + m - 1 - k] = 1 - chs[n + m - 1 - k];
}
results.add(getString(chs));
j += r; // 让j指向j后面第r个长点的位置
int s = 0; // 用于记录j+1后面是短点且继续移动的步数 方便j回位
while (j + 1 < chs.length && j > i) { // 依次将连续的几个长点一个一个的移动到最后
// j>i 是防止j移动了未开始移动的长点
chs[j] = 1 - chs[j]; // 1100 1010 1001 0101 0011
chs[j + 1] = 1 - chs[j + 1];
results.add(getString(chs));
// 如果当前的长点没有移动到底 且下一个元素是短点 就继续让j++ 移动元素
if (j + 2 < chs.length && chs[j + 2] == 0) {
j++;
s++;
} else { // 元素移动到尾了或是下一个元素还是长点
j -= s; // 就让j减去增加的步数s 并让s置0
j--;
s = 0;
}
}
}
r++;
}
return results;
}
}