Азбука Морзе + Шифр Цезаря [дубликат]

93
27 августа 2021, 06:40
На этот вопрос уже дан ответ здесь:
Как декодировать текст из Азбуки Морзе? (1 ответ)
Закрыт 1 год назад.

Всем добрый день! В общем не знаю, сможет ли кто помочь, так как вопрос сложный и объёмный, но все же отпишусь. Пошел я на курсы по java, знания базовой части есть, но опыта пока очень мало. И дали нам первое домашнее задание - дописать код, чтобы программа могла кодировать/раскодировать Азбуку морзе и шифр Цезаря. Честно - сидел вечер четверга и весь день пятницы, сегодня на работе до вечера, до 12 ночи нужно сдать , а я практически не продвинулся, по крайней мере не работает то, что я дописал =( Буду очень благодарен, если кто-нибудь обьяснит хотя бы, что мне нужно делать, знаю только, что используется в программе фабричный метод проектирования. Код дал базовый, без своих изменений.

 package org.geekhub.lesson1;
    import org.geekhub.lesson1.coders.Decoder;
    import org.geekhub.lesson1.coders.DecodersFactory;
    import org.geekhub.lesson1.coders.Encoder;
    import org.geekhub.lesson1.coders.EncodersFactory;
    import java.util.Objects;
    public class Lesson1Main {
        public static void main(String[] args) {
            if (args.length != 2) {
                throw new IllegalArgumentException("Invalid number of parameters. Expected 2, got " + args.length);
            }
            final String algorithm = args[0];
            final String initialString = args[1];
            System.out.println("Initial: " + initialString);
            System.out.println("Algorithm: " + initialString);
            final Encoder encoder = EncodersFactory.getEncoder(algorithm);
            final String encoded = encoder.encode(initialString);
            System.out.println("Encoded: " + encoded);
            final Decoder decoder = DecodersFactory.getDecoder(algorithm);
            final String decoded = decoder.decode(encoded);
            System.out.println("Decoded: " + decoded);
            if (!Objects.equals(initialString, decoded)) {
                throw new IllegalStateException("Initial and decoded strings mismatch");
            }
        }
    }


         package org.geekhub.lesson1.coders;
          public enum Algorithms {
             CAESAR,
             MORSE;

          package org.geekhub.lesson1.coders;
          public interface Decoder {
          String decode(String input);
              }

          package org.geekhub.lesson1.coders;
          public interface Encoder {
          String encode(String input);
            }

        package org.geekhub.lesson1.coders;
        import org.geekhub.lesson1.util.NotImplementedException;
        public class DecodersFactory {

 public static Decoder getDecoder(String name) {
        Algorithms algorithm = Algorithms.valueOf(name);
        Decoder decoder = null;
        switch (algorithm) {
            case MORSE:
                decoder = new MorseCodec().decode();
                break;
            case CAESAR:
                decoder = new CaesarCodec().decode();
                break;
            default:
                throw new IllegalArgumentException("Wrong  type:" + decoder);
        }
        return decoder;
    }
}

        package org.geekhub.lesson1.coders;
        import org.geekhub.lesson1.util.NotImplementedException;
        public class EncodersFactory {
           public class EncodersFactory  {
    public static Encoder getEncoder(String name)   {
        Algorithms algorithm = Algorithms.valueOf(name);
        Encoder encoder = null;
        switch (algorithm) {
            case MORSE:
                encoder = new MorseCodec().encode(input);
                break;
            case CAESAR:
                encoder = new CaesarCodec().encode(input);
                break;
            default:
                throw new IllegalArgumentException("Wrong  type:" + encoder);
        }
        return encoder;

    package org.geekhub.lesson1.util;
    public class NotImplementedException extends RuntimeException {
        public NotImplementedException() {
            super("Implement me, please!");
        }
    }

    package org.geekhub.lesson1.coders;
    import org.geekhub.lesson1.util.NotImplementedException;
    class MorseCodec implements Encoder, Decoder {
           @Override
        static final char[] english = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
                'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
                'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
                ',', '.', '?' };
        static final String[] morse = { ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..",
                ".---", "-.-", ".-..", "--", "-.", "---", ".---.", "--.-", ".-.",
                "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", ".----",
                "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.", "-----",
                "--..--", ".-.-.-", "..--.." };
        public String encode(String input) {
            input = input.toLowerCase();
            char[] chars = input.toCharArray();
            String str = "";
            for (int i = 0; i < chars.length; i++){
                for (int j = 0; j < english.length; j++){
                    if (english[j] == chars[i]){
                        str = str + morse[j] + " ";
                    }
                }
            }
            return str;
        }
        @Override
        public String decode(String input) {
            String[] letters = input.split(" ");
            String str = "";
            for (int i = 0; i < letters.length; i++){
                for (int j = 0; j < morse.length; j++){
                    if (morse[j].equals(letters[i])){
                        str = str + english[j];
                    }
                }
            }
            return str;
        }
    }

    package org.geekhub.lesson1.coders;
    import org.geekhub.lesson1.util.NotImplementedException;
    class CaesarCodec implements Encoder, Decoder {
       public static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";

        @Override
        public String encode(String input) {
            {
                int shiftKey = 3;
                input = input.toLowerCase();
                String cipherText = "";
                for (int i = 0; i < input.length(); i++) {
                    char replaceVal = input.charAt(i);
                    int charPosition = ALPHABET.indexOf(replaceVal);
                    if (charPosition != -1) {
                        int keyVal = (shiftKey + charPosition) % 26;
                        replaceVal = ALPHABET.charAt(keyVal);
                    }
                    cipherText += replaceVal;
                }
                return cipherText;
            }
        }
        @Override
        public String decode(String input) {
            int shiftKey = 3;
            input = input.toLowerCase();
            String plainText = "";
            for (int i = 0; i < input.length(); i++)
            {
                char replaceVal = input.charAt(i);
                int charPosition = ALPHABET.indexOf(replaceVal);
                if(charPosition != -1) {
                    int keyVal = (charPosition - shiftKey) % 26;
                    if (keyVal < 0) {
                        keyVal = ALPHABET.length() + keyVal;
                    }
                    replaceVal = ALPHABET.charAt(keyVal);
                }
                plainText += replaceVal;
            }
            return plainText;
        }
    }
Answer 1

Вы заблудились в двух соснах. Посему хочу показать вам немного измененное решение. Изменения состоят в том, что здесь нет классов-фабрик. Все дело в том, что каноническое представление паттерна фабричный метод предусматривает такие классы, однако в реальной жизни этот метод давно выродился до соответствующих методов в классе - родителе(именно так сделал я). Кроме того я немного подправил энам, потому как в вашем случае он выполняет очень странную роль - он образуется из стринга, чтобы по нему в дальнейшем фабрика каким-то способом создала и венула новый экземпляр класса (тогда почему это не сделать по стрингу). Кроме того, в этом случае вы увидите , что энам может выполнять роль не только простого перечисления.

public class Lesson1Main {
    public static void main(String[] args) {
        final String algorithm = Algorithms.CAESAR.name();
        final String initialString = "dima";
        System.out.println("Initial: " + initialString);
        System.out.println("Algorithm: " + algorithm);
        final Encoder encoder = Coder.getEncoder(algorithm);
        final String encoded = encoder.encode(initialString);
        System.out.println("Encoded: " + encoded);
        final Decoder decoder = Coder.getDecoder(algorithm);
        final String decoded = decoder.decode(encoded);
        System.out.println("Decoded: " + decoded);
        if (!Objects.equals(initialString, decoded)) {
            throw new IllegalStateException("Initial and decoded strings mismatch");
        }
    }
}

public enum Algorithms {
    CAESAR(new CaesarCodec()),
    MORSE(new MorseCodec());
    private final Coder coder;
    private Algorithms(Coder coder) {
        this.coder = coder;
    }
    public Decoder getDecoder() {
        return coder;
    }
    public Encoder getEncoder() {
        return coder;
    }
}
public interface Decoder {
    String decode(String input);
}
public interface Encoder {
    String encode(String input);
}
public abstract class Coder implements Encoder, Decoder {
    public static Decoder getDecoder(String name) {
        return Algorithms.valueOf(name).getDecoder();
    }
    public static Encoder getEncoder(String name) {
        return Algorithms.valueOf(name).getEncoder();
    }
}
public class CaesarCodec extends Coder {
    private static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";
    @Override
    public String encode(String input) {
        {
            int shiftKey = 3;
            input = input.toLowerCase();
            String cipherText = "";
            for (int i = 0; i < input.length(); i++) {
                char replaceVal = input.charAt(i);
                int charPosition = ALPHABET.indexOf(replaceVal);
                if (charPosition != -1) {
                    int keyVal = (shiftKey + charPosition) % 26;
                    replaceVal = ALPHABET.charAt(keyVal);
                }
                cipherText += replaceVal;
            }
            return cipherText;
        }
    }
    @Override
    public String decode(String input) {
        int shiftKey = 3;
        input = input.toLowerCase();
        String plainText = "";
        for (int i = 0; i < input.length(); i++) {
            char replaceVal = input.charAt(i);
            int charPosition = ALPHABET.indexOf(replaceVal);
            if (charPosition != -1) {
                int keyVal = (charPosition - shiftKey) % 26;
                if (keyVal < 0) {
                    keyVal = ALPHABET.length() + keyVal;
                }
                replaceVal = ALPHABET.charAt(keyVal);
            }
            plainText += replaceVal;
        }
        return plainText;
    }
}
class MorseCodec extends Coder {
    private static final char[] ENGLISH = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
        'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
        'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
        ',', '.', '?'};
    private static final String[] MORSE = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..",
        ".---", "-.-", ".-..", "--", "-.", "---", ".---.", "--.-", ".-.",
        "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", ".----",
        "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.", "-----",
        "--..--", ".-.-.-", "..--.."};
    @Override
    public String encode(String input) {
        input = input.toLowerCase();
        char[] chars = input.toCharArray();
        String str = "";
        for (int i = 0; i < chars.length; i++) {
            for (int j = 0; j < ENGLISH.length; j++) {
                if (ENGLISH[j] == chars[i]) {
                    str = str + MORSE[j] + " ";
                }
            }
        }
        return str;
    }
    @Override
    public String decode(String input) {
        String[] letters = input.split(" ");
        String str = "";
        for (int i = 0; i < letters.length; i++) {
            for (int j = 0; j < MORSE.length; j++) {
                if (MORSE[j].equals(letters[i])) {
                    str = str + ENGLISH[j];
                }
            }
        }
        return str;
    }
}
Answer 2

Как бы делал я, из того, что вы написали.

У нас есть типы кодировщиков

public enum Algorithms {
    CAESAR,
    MORSE;
}

Интерфейсы

public interface Encoder {
    String encode(String input);
}
public interface Decoder {
    String decode(String input);
}

Цезарь кодируется элементарно

public class CaesarCodec implements Encoder, Decoder {
    public static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";
    private int _shift;
    public CaesarCodec(int shift) {
        this._shift = shift;
    }
    @Override
    public String encode(String input) {
        StringBuilder ret = new StringBuilder();
        for(int i=0; i<input.length(); i++)
            ret.append(ALPHABET.charAt((ALPHABET.indexOf(input.charAt(i)) + _shift)%ALPHABET.length()));
        return ret.toString();
    }
    @Override
    public String decode(String input) {
        StringBuilder ret = new StringBuilder();
        for(int i=0; i<input.length(); i++)
            ret.append(ALPHABET.charAt((ALPHABET.indexOf(input.charAt(i)) - _shift + ALPHABET.length())%ALPHABET.length()));
        return ret.toString();
    }
}

Морзе - менее лакончино, ну и я добавил хеш таблиц для скорости

public class MorseCodec implements Encoder, Decoder {
    static final HashMap<Character, String> _encodeMap = new HashMap<>();
    static final HashMap<String, Character> _decodeMap = new HashMap<>();
    static final char[] english = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
            'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
            'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
            ',', '.', '?' };
    static final String[] morse = { ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..",
            ".---", "-.-", ".-..", "--", "-.", "---", ".---.", "--.-", ".-.",
            "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", ".----",
            "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.", "-----",
            "--..--", ".-.-.-", "..--..", };
    public MorseCodec(){
        for(int i=0; i<english.length; i++)
        {
            _encodeMap.put(english[i], morse[i]);
            _decodeMap.put(morse[i], english[i]);
        }
    }
    @Override
    public String encode(String input) {
        StringBuilder ret = new StringBuilder();
        for(int i=0; i<input.length(); i++)
        {
            ret.append(_encodeMap.get(input.charAt(i)));
            ret.append(" ");
        }
        return ret.toString().trim();
    }
    @Override
    public String decode(String input) {
        String[] letters = input.split(" ");
        StringBuilder ret = new StringBuilder();
        for(int i=0; i<letters.length; i++)
            ret.append(_decodeMap.get(letters[i]));
        return ret.toString();
    }
}

Фабрика, простейший вариант

public class Factory{
    public Encoder getEncoder(Algorithms type){
        if (type == Algorithms.CAESAR) return new CaesarCodec(3);
        if (type == Algorithms.MORSE) return new MorseCodec();
        throw new IllegalArgumentException("type");
    }
    public Decoder getDecoder(Algorithms type){
        if (type == Algorithms.CAESAR) return new CaesarCodec(3);
        if (type == Algorithms.MORSE) return new MorseCodec();
        throw new IllegalArgumentException("type");
    }
}

Проверка

public static void main(String[] args) {
    Factory factory = new Factory();
    Encoder morseEncoder = factory.getEncoder(Algorithms.MORSE);
    Decoder morseDecoder = factory.getDecoder(Algorithms.MORSE);
    System.out.println(morseEncoder.encode("hello"));
    System.out.println(morseDecoder.decode(".... . .-.. .-.. ---"));
    Encoder caesarEncoder = factory.getEncoder(Algorithms.CAESAR);
    Decoder caesarDecoder = factory.getDecoder(Algorithms.CAESAR);
    System.out.println(caesarEncoder.encode("hello"));
    System.out.println(caesarDecoder.decode("khoor"));
}

Вывод

.... . .-.. .-.. ---
hello
khoor
hello

Контроль правильности ввода уже думайте сами.

READ ALSO
Преобразование Drawable

Преобразование Drawable

Начал свое знакомство с Realm и столкнулся с проблемой что такие классы как Calendar и Drawable не поддерживаются Realm, оно и логичноCalendar я стал хранить...

134
Многоядерная обработка Java-программы

Многоядерная обработка Java-программы

Помогите разобраться с многоядерной обработкой Java-программы

109
Как из строки сгенерировать png?

Как из строки сгенерировать png?

Есть класс, который генерирует svg (строка)Дальше эту строку я вставляю в html

89
Вернуть объект с измененным свойством - JS

Вернуть объект с измененным свойством - JS

Мне нужно найти элемент в объекте у которого есть определенное свойство , я это уже сделал вот таким кодом - result = thisstate

119