Szyfr Cezara - ocena rozwiązania

Odpowiedz Nowy wątek
2017-03-20 19:03
0

Jak ocenicie takie rozwiązanie? Da się to zrobić prościej (bardziej intuicyjnie)?

public String encode(String enc, int offset) {
         offset %= 26;
 
         StringBuilder result = new StringBuilder();
 
         for (int i = 0; i < enc.length(); i++) {
             result.append((char) ((enc.charAt(i) % 97 + offset) % 26 + 97));
         }
 
         return result.toString();
     }
 
     public String decode(String enc, int offset) {
         offset %= 26;
 
         StringBuilder result = new StringBuilder();
 
         for (int i = 0; i < enc.length(); i++) {
             result.append((char) ((enc.charAt(i) % 97 - offset) % 26 + 97));
         }
 
         return result.toString();
     }

edytowany 2x, ostatnio: Burdzi0, 2017-03-20 19:08

Pozostało 580 znaków

2017-03-20 19:26
2
  1. StringBuilder nie jest Ci potrzebny. Kompilatory od wielu lat optymalizują operator konkatenacji,
  2. Nie używaj magicznych liczb - nazwij je,
  3. Offset osobiście nazwałbym key, skoro to szyfrowanie,
  4. enc to skrót od encefalograf? Nie używaj skrótów.

„Pomnij, że sąd laika, gdy mówi o dziele
O dziele mówi mało; o laiku – wiele!”
— Henryk Elzenberg
edytowany 2x, ostatnio: nie100sowny, 2017-03-20 19:28
Pokaż pozostałe 2 komentarze
@nie100sowny, moim zdaniem w punkcie 1. głosisz głupoty. - bogdans 2017-03-20 23:10
@margor90 @bogdans Wydajnościowo mogę się mylić (kompilator zoptymalizuje nawet pętlę, ale nie maksymalnie, za każdym razem prawdopodobnie będzie tworzony nowy Builder). Mimo tego dopóki nie zobaczę wykresów taka optymalizacja jest bezzasadna. Nigdy nie optymalizujemy kosztem czytelności: gdy nie ma konieczności, nie zmierzymy lub ostatni przypadek piszemy maturę, którą jakiś nauczyciel będzie czytał :D - nie100sowny 2017-03-21 00:35
@nie100sowny: w tym programie zapewne StringBuilder jest zbyteczny - kodowane i dekodowane Stringi są raczej krótkie. Ale Ty napisałeś Kompilatory od wielu lat optymalizują operator konkatenacji,, a to nie jest prawdą. - bogdans 2017-03-21 09:17
@bogdans Wyjaśnij proszę co jest nie tak w tym zdaniu. - nie100sowny 2017-03-21 13:49
@nie100sowny: To: kompilator Oracle'a nie optymalizuje operatora konkatenacji umieszczonego w pętli. http://ideone.com/lDLw51 - bogdans 2017-03-21 17:05

Pozostało 580 znaków

2017-03-20 19:31
1
    public final int NUMBER_OF_LETTERS_IN_ALPHABET = 'z' - 'a' + 1 ;
    public final int LETTER_VALUE = 'a';
 
     public String encode(String message, int key) {
         key %= NUMBER_OF_LETTERS_IN_ALPHABET;
 
         StringBuilder result = new StringBuilder();
 
         for (int i = 0; i < message.length(); i++) {
             result.append((char) ((message.charAt(i) % LETTER_VALUE + key) % NUMBER_OF_LETTERS_IN_ALPHABET + LETTER_VALUE));
         }
 
         return result.toString();
     }
 
     public String decode(String message, int key) {
         key %= NUMBER_OF_LETTERS_IN_ALPHABET;
 
         StringBuilder result = new StringBuilder();
 
         for (int i = 0; i < message.length(); i++) {
             result.append((char) ((message.charAt(i) % LETTER_VALUE - key) % NUMBER_OF_LETTERS_IN_ALPHABET + LETTER_VALUE));
         }
 
         return result.toString();
     }

Coś takiego? (Konwencja do poprawy, bardziej chodzi mi o zamysł)


edytowany 4x, ostatnio: Burdzi0, 2017-03-20 20:13
Pokaż pozostałe 3 komentarze
@nie100sowny: Wziąłem pod uwagę ;) rzuć okiem na edycję :D - Burdzi0 2017-03-20 19:40
@Burdzi0 Tylko po co te magiczne liczby? - spartanPAGE 2017-03-20 20:02
@spartanPAGE: Rozwiń proszę, bo niekoniecznie rozumiem co masz na myśli :) - Burdzi0 2017-03-20 20:03
@Burdzi0: lepiej stosować w tym wypadku wyrażenia niż stałe, 26 = 'z' - 'a' + 1, 97 = 'a' - vpiotr 2017-03-20 20:07
@vpiotr: Poprawiłem. Chodzi o czytelność? - Burdzi0 2017-03-20 20:14

Pozostało 580 znaków

2017-03-20 19:35

Podejście dobre, i nic raczej nie ulepszysz, oprócz czytelności, użyciu operatora +, oraz można by atakować to Stream Api

Do matury spokojnie wystarczy, idź ogarniaj MS Access :D

EDIT: I potem kierunek studiów który respektuje maturę z infy, lub skup się na majcy.


„Pomnij, że sąd laika, gdy mówi o dziele
O dziele mówi mało; o laiku – wiele!”
— Henryk Elzenberg
edytowany 4x, ostatnio: nie100sowny, 2017-03-20 19:38
Javę biorę na poważnie, nie tylko do matury ;) Śmiejesz się z Accessa, a ja muszę to ogarnąć xd kuję jedno i drugie, staram się jak mogę, ale wątpię, żeby się udało, rzuć okiem :P - Burdzi0 2017-03-20 19:50
Nie śmieję się, sam uwielbiałem informatykę w licbazie i zdałem ją bardzo dobrze (Accessa też :) ). Niestety matematyka okazała się ważniejsza pomimo 100% z podstawy i 50 z rozszerzenia nie starczyło na wymarzony kierunek. Choć kończąc obecnie studbazę, oceniam to nie najgorzej, łatwiej było mi pogodzić studia z pracą. - nie100sowny 2017-03-20 20:55
@nie100sowny: a jaki kierunek jeśli można zapytać? :) - Burdzi0 2017-03-22 08:11

Pozostało 580 znaków

2017-03-20 19:45
0

StringBuildera oczywiście zostaw. Kompilator ogarnie proste konkatenacje, ale już tego co napisałeś - w wersji ze Stringiem już nie. A przynajmniej tak mówi dekompilator w IntelliJ.


"A human being should be able to change a diaper, plan an invasion, butcher a hog, conn a ship, design a building, write a sonnet, balance accounts, build a wall, set a bone, comfort the dying, take orders, give orders, cooperate, act alone, solve equations, analyze a new problem, pitch manure, program a computer, cook a tasty meal, fight efficiently, die gallantly. Specialization is for insects." Robert Heinlein.
Poleganie na optymalizacji kompilatora to nie jest dobre podejście. Jeśli explicite tworzysz nowe mutowalne obiekty w pętli, to kompilator może, ale nie musi ci tego ogarnąć. Lepiej pisać poprawnie. - datdata 2017-03-20 19:51
@datdata: no co ty? jak "gupi" kompilator to się go zmienia. nie po to ludzie pisali te kompilatorym, żeby za nie robotę odwalać. - jarekr000000 2017-03-20 19:56
Wrócił StringBuilder. Widziałem taką prezentację (od strony 24), ale stwierdziłem, że na moje potrzeby nie muszę korzystać z nowego obiektu. Muszę się nauczyć dobrych nawyków. - Burdzi0 2017-03-20 19:57
@jarekr000000: A zagwarantujesz, że ktoś kto pobierze sobie twój kod będzie miał te tricki włączone lub dostępne w kompilatorze? Trzeba pisać dobry kod (tym bardziej, że użycie SB jest bezbolesne), a nie liczyć, że kompilator magicznie naprawi cały kiepski kod. - datdata 2017-03-20 20:02
@datdata - Kod się pisze dla ludzi, nie dla kompilatora. Nawet jak użyjesz StringBuildera to i tak nie zagwarantujesz, że ktoś nie ma tak "gupiego" kompilatora, że np. przepisuje to na String + . Szach i mat ateisto. - jarekr000000 2017-03-20 20:05

Pozostało 580 znaków

2017-03-20 20:23
1

Trochę lepsza mutacja:

http://ideone.com/p8VSJY

  • sprawdzenie czy możemy szyfrować znak
  • wyeliminowany append
  • weliminowane liczby magiczne
  • poprawione wyrażenie szyfrujące

Pozostało 580 znaków

2017-03-20 22:30
2

Skąd macie informacje, że kompilator zoptymalizuje? U mnie (Java 1.8.111) pętla

        StringBuilder result = new StringBuilder("");
        for (int i=1;i<=100000;i++)
        {
            result.append("A");
        }

wykonuje się około 10 tys. razy szybciej niż pętla

        String result = "";
        for (int i=1;i<=100000;i++)
        {
            result+="A";
        }

To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
Bo JIT tego nie zoptymalizuje :) - Koziołek 2017-03-20 22:46

Pozostało 580 znaków

2017-03-20 22:45
0
bogdans napisał(a):

Skąd macie informacje, że kompilator zoptymalizuje? U mnie (Java 1.8.111) pętla

        StringBuilder result = new StringBuilder("");
        for (int i=1;i<=100000;i++)
        {
            result.append("A");
        }

wykonuje się około 10 tys. razy szybciej niż pętla

        String result = "";
        for (int i=1;i<=100000;i++)
        {
            result+="A";
        }

W pętli kompilator nie jest w stanie zoptymalizować i nie zamienia konkatenacji na StringBuildera. Poza pętlami w zdecydowanej większości raczej tak, jednakże poleganie na tym co może zrobić kompilator, a co nie jest zdecydowanie słabe.

Pozostało 580 znaków

2017-03-20 23:06
1

A teraz ja dorzucę swoje 3 grosze. Rozwiązanie może i jest OK, ale nie uwzględnia kilku rzeczy i nie wykorzystuje elementów Javy 8.

  • nulle i null checki. Mała rzecz, a cieszy.
  • enc.charAt(i) zamień na toCharArray() i dalej na Stream.
  • nie uwzględniasz znaków diakrytycznych, ale da się bez tego przeżyć.

Pozostało 580 znaków

2017-03-22 09:04
0

Rozwiązanie @vpiotr jest najlepsze. Tutaj wszystkich przepraszam za niedoprecyzowanie.
Na wejściu dostaję plik tekstowy z wyrazami do zaszyfrowania i przesunięciem. Nie ma opcji na nulle (tzn. jest, ale takie zadania z automatu nie są brane pod uwagę, tak było z kolejnym podpunktem zadania), wydajność przy paru tysięcy wyrazów nie gra wielkiej roli.
@Koziołek nie znam jeszcze api streamów, więc to troszkę odpada, zwłaszcza, że miałem problemy z implementacją :/
Znaki diakrytyczne się nie pojawiają, więc kolejny problem z głowy ;)
Dziękuję wszystkim obecnym w wątku za pomoc :)


Uwaga: moje rozwiązanie szyfruje tylko małe litery (tak jak w oryginalnym poście). - vpiotr 2017-03-22 09:41
@vpiotr: Tak, zdaję sobie z tego sprawę ;) - Burdzi0 2017-03-22 11:32

Pozostało 580 znaków

2017-03-22 12:41
0

Ja chciałbym poprzeć podpowiedz @Koziołek i wprowadzić lekką dygresję.
Kiedy uczyłem się Javy w 2014 roku, nasz nauczyciel nie wprowadzał Javy 8.
Odbiło się to potężnie na mojej dalszej nauce tego języka. Oczywiście niekorzystnie. Nabrałem "starych" nawyków. Nie dotknąłem przez to paradygmatu funkcyjnego. Nawet tak okrojonego jak w Javie 8.

Dopiero po skończonym semestrze musiałem uczyć się bardzo dużej ilości zmian i zmienić często tok myślenia. Uważam, że powinno byc obowiązkiem obcowanie z Javą 8 od początku nauki Javy, od pierwszych linijek kodu.

edytowany 2x, ostatnio: InterruptedException, 2017-03-22 12:42

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0