专栏首页渔夫Java MorseCoder - Java 语言实现的摩尔斯电码编码解码器

Java MorseCoder - Java 语言实现的摩尔斯电码编码解码器

最近在看《编码-隐匿在计算机软件背后的语言》这本书,看到了一张译码表很有意思:

不免让我会想起本科在学编码的那段轻松岁月,于是就去查了如何用Java代码实现这个摩尔的编码和译码过程,代码如下(代码是转载的): MorseCoder是主类,Test是测试用类:

import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

public final class MorseCoder {

    private static final Map<Integer, String> alphabets = new HashMap<>();    // code point -> morse
    private static final Map<String, Integer> dictionaries = new HashMap<>(); // morse -> code point

    private static void registerMorse(Character abc, String dict) {
        alphabets.put(Integer.valueOf(abc), dict);
        dictionaries.put(dict, Integer.valueOf(abc));
    }

    static {
        // Letters
        registerMorse('A', "01");
        registerMorse('B', "1000");
        registerMorse('C', "1010");
        registerMorse('D', "100");
        registerMorse('E', "0");
        registerMorse('F', "0010");
        registerMorse('G', "110");
        registerMorse('H', "0000");
        registerMorse('I', "00");
        registerMorse('J', "0111");
        registerMorse('K', "101");
        registerMorse('L', "0100");
        registerMorse('M', "11");
        registerMorse('N', "10");
        registerMorse('O', "111");
        registerMorse('P', "0110");
        registerMorse('Q', "1101");
        registerMorse('R', "010");
        registerMorse('S', "000");
        registerMorse('T', "1");
        registerMorse('U', "001");
        registerMorse('V', "0001");
        registerMorse('W', "011");
        registerMorse('X', "1001");
        registerMorse('Y', "1011");
        registerMorse('Z', "1100");
        // Numbers
        registerMorse('0', "11111");
        registerMorse('1', "01111");
        registerMorse('2', "00111");
        registerMorse('3', "00011");
        registerMorse('4', "00001");
        registerMorse('5', "00000");
        registerMorse('6', "10000");
        registerMorse('7', "11000");
        registerMorse('8', "11100");
        registerMorse('9', "11110");
        // Punctuation
        registerMorse('.', "010101");
        registerMorse(',', "110011");
        registerMorse('?', "001100");
        registerMorse('\'', "011110");
        registerMorse('!', "101011");
        registerMorse('/', "10010");
        registerMorse('(', "10110");
        registerMorse(')', "101101");
        registerMorse('&', "01000");
        registerMorse(':', "111000");
        registerMorse(';', "101010");
        registerMorse('=', "10001");
        registerMorse('+', "01010");
        registerMorse('-', "100001");
        registerMorse('_', "001101");
        registerMorse('"', "010010");
        registerMorse('$', "0001001");
        registerMorse('@', "011010");
    }

    private final char dit; // short mark or dot
    private final char dah; // longer mark or dash
    private final char split;

    public MorseCoder() {
        this('.', '-', '/');
    }

    public MorseCoder(char dit, char dah, char split) {
        this.dit = dit;
        this.dah = dah;
        this.split = split;
    }

    public String encode(String text) {
        if (text == null) {
            throw new IllegalArgumentException("Text should not be null.");
        }
        StringBuilder morseBuilder = new StringBuilder();
        text = text.toUpperCase();
        for (int i = 0; i < text.codePointCount(0, text.length()); i++) {
            int codePoint = text.codePointAt(text.offsetByCodePoints(0, i));
            String word = alphabets.get(codePoint);
            if (word == null) {
                word = Integer.toBinaryString(codePoint);
            }
            morseBuilder.append(word.replace('0', dit).replace('1', dah)).append(split);
        }
        return morseBuilder.toString();
    }

    public String decode(String morse) {
        if (morse == null) {
            throw new IllegalArgumentException("Morse should not be null.");
        }
        StringBuilder textBuilder = new StringBuilder();
        StringTokenizer tokenizer = new StringTokenizer(morse, String.valueOf(split));
        while (tokenizer.hasMoreTokens()) {
            String word = tokenizer.nextToken().replace(dit, '0').replace(dah, '1');
            Integer codePoint = dictionaries.get(word);
            if (codePoint == null) {
                codePoint = Integer.valueOf(word, 2);
            }
            textBuilder.appendCodePoint(codePoint);
        }
        return textBuilder.toString();
    }

}


class Test{

    public static void main(String[] args) {
        MorseCoder morseCoder = new MorseCoder();
        System.out.println(morseCoder.encode("Hello World!"));
        System.out.println(morseCoder.decode("...././.-../.-../---/-...../.--/---/.-./.-../-../-.-.--/"));

    }
}

控制台输出:

...././.-../.-../---/-...../.--/---/.-./.-../-../-.-.--/
HELLO WORLD!

效率上在查表过程应该还能提升,但是Demo足够简单就好! 备注: StringBuilder用于字符串需要进行拼接操作,StringTokenizer用于指定分隔符下的分隔字符串操作。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java-Lambda表达式和“方法引用”的对比和详解

     Lambda表达式是Java 8 添加的一个新特性,可以认为,Lambda是一个匿名函数(相似于匿名内部类),作用是返回一个实现了接口的对象(这个观点非常重要...

    Fisherman渔夫
  • linux命令英文缩写的含义(方便记忆)

    版权声明: h...

    Fisherman渔夫
  • Java-ThreadGroup类源代码分析与学习

    Fisherman渔夫
  • java之Lambda表达式

    上面的一段代码和之前的除了参数传递方式不同,其他都一样,第一段代码用匿名内部类的方式实现参数传递,第二段代码用Lambda表达式实现参数传递。

    说故事的五公子
  • Robot Framework(2)- 快速安装

    https://www.cnblogs.com/poloyy/category/1770899.html

    小菠萝测试笔记
  • 小人脸检测 - Finding Tiny Faces

    https://www.cs.cmu.edu/~peiyunh/tiny/index.html code: https://github.com/peiyu...

    用户1148525
  • Access更新查询

    大家好,上节介绍了操作查询中的生成表查询,本节介绍更新查询的内容。操作查询的注意点上节有介绍过,不重复说明。

    无言之月
  • 解读目标检测新范式:Segmentations is All You Need

    作者利用注释质量较差的边界框在困难环境中实现稳健的目标检测性能,避免了与 anchor 框或 NMS 相关的所有超参数。他们提出的模型超越了之前基于 ancho...

    AI算法与图像处理
  • 资本上升、巨头下沉,破茧成蝶的新零售未来在哪?

    当阿里、腾讯、京东在新零售领域不断混战,人们越来越开始清晰地感觉到新零售时代已经来临。移动互联网时代,人们对于这些头部互联网公司商业模式的效仿最终让越来越多的人...

    孟永辉
  • 【JavaWeb】112:收藏功能的实现

    创建FavoriteServlet接受请求,在isFavorite方法中编写代码:

    刘小爱

扫码关注云+社区

领取腾讯云代金券