有一个代码可以解密引入字符串的地方,然后用双号解密,字母可以是a到j,分别是a = 0,b = 1 ... j = 9。 该程序有效,我想知道也许有一种最简单的方法来实现这一目标吗?我是java的新手,目前还不知道所有的功能。 代码:
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.lang.Double;
public class Decrypt
{
private static String conversionTable[][] = {
{"a", "0"},
{"b", "1"},
{"c", "2"},
{"d", "3"},
{"e", "4"},
{"f", "5"},
{"g", "6"},
{"h", "7"},
{"i", "8"},
{"j", "9"},
};
private static Scanner scanner;
public static double decrypt(String encryptedNumber)
{
String c = "";
int i = 0;
String[] s = encryptedNumber.split("");
for(int j = 0; j < 2; j++) {
if(c.length() == s.length)
break;
for(int k = 0; k < 9; k++) {
if(c.length() == s.length)
break;
if(conversionTable[k][j].equalsIgnoreCase(s[i])){
c += k;
i++;
}else if(s[i].equalsIgnoreCase(".")){
c += ".";
i++;
}
}
j--;
}
double d = Double.parseDouble(c);
return d;
}
public static void main(String arg[])
{
scanner = new Scanner(System.in);
System.out.println("Enter the string to decrypt:");
String input=scanner.next();
System.out.println("Number after decryption is:"+decrypt(input));
}
}
答案 0 :(得分:0)
从加密的角度来看,您所描述的是substitution cipher。我甚至不再考虑这种加密,更像是编码(参见here)。
你有字符串添加到字符串。当你做
之类的事情c += k;
Java实际上在做什么是创建一个新的String对象并将c中的指针更改为该新对象。多年来,JVM在创建和丢弃短期对象时变得更好,但这仍然非常低效。请尝试使用StringBuilder。
您还通过convertTable执行了sequential search,这意味着您的整个算法都是O(n ^ 2)操作(请参阅here)(对于挑剔者来说,它实际上是O(m *) n)但这对我来说足够接近了)。与这样一个小桌子完全无关,但如果可能的话,避免做那样的事情。另外,当语言中的某些东西想要为你做这件事时(这将是一个反复出现的主题),自己写它是没有意义的。您的项目是有序的,因此我们可以利用Arrays中的一个binarySearch()实现。我会稍微设想一下这个用法,但这只是为了说明。
您可以利用增强的for循环来迭代大多数列表。我甚至会说,如果你不能使用增强型for循环,那么你应该认真考虑一个while循环。
避免在交换机以外的任何地方使用break语句。大多数人会认为他们和goto在同一条船上。
为变量提供更具描述性的名称。你未来的自我会感谢你。
因此,根据我所概述的更改,我们最终得到以下decrypt()方法:
public static double decrypt(String encryptedNumber) {
StringBuilder builder = new StringBuilder();
int i = 0;
String[] encNumElements = encryptedNumber.toLowerCase().split("");
for (String element : encNumElements) {
int foundAt = Arrays.binarySearch(conversionTable, new String[]{element, ""}, new Comparator<String[]>() {
@Override
public int compare(String[] arg0, String[] arg1) {
return arg0[0].compareTo(arg1[0]);
}
});
if (foundAt >= 0) {
builder.append(conversionTable[foundAt][1]);
} else {
// assuming a decimal point here since it's not on the list
builder.append('.');
}
}
double d = Double.parseDouble(builder.toString());
return d;
}
这只是好一点。如果我真的想做这样的事情,比较器将是一个单独的类,但这可以用于说明。
从编码的角度来看,这里有一个查找表。简单的实现是Map。传统上,初始化静态查找映射有点难看,但请查看i_am_zero的答案here,以便用Java 8进行更简洁的方式。映射是一种自然搜索结构,因此顺序并不重要。它还具有很好的副作用,即将小数点放入Map中,从而消除if语句。
private static final Map<String, String> conversionMap = Stream.of(
new SimpleEntry<>("a", "0"),
new SimpleEntry<>("b", "1"),
new SimpleEntry<>("c", "2"),
new SimpleEntry<>("d", "3" ),
new SimpleEntry<>("e", "4"),
new SimpleEntry<>("f", "5"),
new SimpleEntry<>("g", "6"),
new SimpleEntry<>("h", "7" ),
new SimpleEntry<>("i", "8"),
new SimpleEntry<>("j", "9"),
new SimpleEntry<>(".", "."))
.collect(Collectors.toMap((se) -> se.getKey(), (se) -> se.getValue()));
public static double decrypt(String encryptedNumber) {
StringBuilder builder = new StringBuilder();
String[] encNumElements = encryptedNumber.toLowerCase().split("");
for (String element : encNumElements) {
builder.append(conversionMap.get(element));
}
double d = Double.parseDouble(builder.toString());
return d;
}
这样的事情是我会在一般情况下停下来的地方。但是您的查找列表是一系列整数序列的字符。 Java实际上确实将原始字符视为整数,因此您可以对它们进行数学运算。 String甚至为我们提供了一个从String中获取字符的方法,因此我们可以直接遍历它们。我们必须再次处理if中的小数点,但它可以让我们完全摆脱查找表。
public static double decrypt(String encryptedNumber) {
StringBuilder builder = new StringBuilder();
for (char ch : encryptedNumber.toLowerCase().toCharArray()) {
if (ch == '.') {
builder.append('.');
} else {
builder.append(ch - 'a');
}
}
return Double.parseDouble(builder.toString());
}