在没有电话的时代,摩尔斯电码是无线电传输领域中的一种常用代码。电码以短信号(短点,o)和长信号(长点,-)的不同组合表示各种文字。 例如:o—表示英文字母J,而—表示英文字母M。 假设有一本以n

在没有电话的时代,摩尔斯电码是无线电传输领域中的一种常用代码。电码以短信号(短点,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;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值