Java code (download).
package net.lookin.lookin_net.algorithm;import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.TreeSet;/* http://look-in.net/2007/12/26/algorithm-caesar-cipher/
Algorithm: Шифр цезаря
categories: algorithm, puzzle — edit
Как известно, http://jump4loves.com/tours/ шифровал сообщения очень просто: Шифр Цезаря (wikipedia).
Пример шифрование с использованием ключа k=3:
Оригинальный текст: Съешь же ещё этих мягких французских булок, да выпей чаю.
Шифрованный текст: Фэзыю йз зьи ахмш пвёнлш чугрщцкфнлш дцосн, жг еютзм ъгб.
Интересны следующие задачи:
1) нужно найти такое русское игровое слово* и число k (ключ) что бы слово преобразовывалось опять в слово из множества слов русского языка.
2) найти такое игровое слово с максимальной длинной.
* - нарицательное существительное в именительном падеже, единственном числе. пример: слесарь, антибиотик.
*/
public class CeaserCipher {
// storing vocabulary
private TreeSet voc = new TreeSet();
// counter for success results
public int count = 0;
// alphabet of letters
private char[] alph = new char[34];
// map of alphabet
private HashMap<character,> map = new HashMap<character,>(
33);
// result of coding
private StringBuffer result = new StringBuffer(30);
public static void main(String[] args) throws IOException {
Date st = new Date();
String fileName = "words.txt";
if ((args != null) && (args.length == 1)) {
fileName = args[0];
}
CeaserCipher cc = new CeaserCipher(fileName);
cc.perform();
Date et = new Date();
System.out.print("time=" + (et.getTime() - st.getTime()) + " count="
+ cc.count);
}
// constructor
public CeaserCipher(String filename) throws IOException {
this.loadVoc(filename);
this.fillConst();
}
// load vocabulary
private void loadVoc(String fileName) throws IOException {
HashSet s = new HashSet(42700);
BufferedReader reader = new BufferedReader(new FileReader(fileName));
String word;
while ((word = reader.readLine()) != null) {
s.add(word);
// System.out.print(word);
}
voc.addAll(s);
}
// perfrom iteration by words and by key
// O(n) ~ 16*words.length*log(words.length) = n*log(n)
public void perform() {
Iterator i = voc.iterator();
while (i.hasNext()) {
String word = (String) i.next();
// the "bad" word
if ((word.indexOf("-") != -1) || (word.indexOf(" ") != -1)) {
continue;
}
for (int k = 1; k < 17; k++) {
if (voc.contains(this.code(word, k))) {
count++;
System.out.println(word + " " + this.code(word, k) + " " + k+" len="+word.length());
}
}
}
}
// perform coding: word using key=k
private String code(String word, int k) {
result.setLength(0);
for (int i = 0; i < word.length(); i++) {
result.append(alph[(map.get(word.charAt(i)) + k) % 33]);
}
return result.toString();
}
// prepare alphabet. Ё - specific
private void fillConst() {
int k = 0;
for (char i = 'а'; i <= 'е'; i++) {
alph[k] = i;
map.put(i, k);
k++;
}
alph[k] = 'ё';
map.put('ё', 7);
k++;
for (char i = 'ж'; i <= 'я'; i++) {
alph[k] = i;
map.put(i, k);
k++;
}
}
}
}