我正在做一个实验,用文字角色扮演游戏(MUD)中的一个表情来解析语音,这样如果你听不清,或者是用另一种语言,你就不会理解它。这是正确的,但我只是想确保它是尽可能清晰和有效的。
import java.util.Scanner;
import java.util.Random;
public class EmoteParser {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter an emote: ");
String emote = scanner.nextLine();
System.out.println("Original emote:\n" + emote);
System.out.println("\nParsed emote:\n" + jumbleEmoteSpeech(emote));
}
public static String jumbleEmoteSpeech(String emote) {
StringBuilder out = new StringBuilder();
int quote1Location = emote.indexOf('"');
if (quote1Location == -1) {
out.append(emote);
}
else {
int quote2Location;
int currentIndex = 0;
boolean found = true;
do {
quote2Location = emote.indexOf('"', quote1Location + 1);
if (quote2Location == -1 || quote2Location < currentIndex) {
out.append(emote.substring(currentIndex));
found = false;
}
else {
out.append(emote.substring(currentIndex, quote1Location + 1));
out.append(jumble(emote.substring(quote1Location + 1, quote2Location)));
currentIndex = quote2Location;
quote1Location = emote.indexOf('"', currentIndex + 1);
}
} while (found);
}
return out.toString();
}
public static String jumble(String text) {
StringBuilder out = new StringBuilder();
Random generator = new Random();
for (int i = 0; i < text.length(); i++) {
char ch = text.charAt(i);
if (Character.isLetter(ch)) {
if (Character.isUpperCase(ch)) {
out.append((char)('A' + generator.nextInt(26)));
}
else {
out.append((char)('a' + generator.nextInt(26)));
}
}
else if (Character.isDigit(ch)) {
out.append((char)('0' + generator.nextInt(10)));
}
else {
out.append(text.charAt(i));
}
}
return out.toString();
}
}另外,使用'"'和"\""有什么真正的好处吗?我认为'"'的可读性更强,而且任何性能差异都可能得到优化。
发布于 2016-04-02 21:20:09
jumble方法在jumble方法中,通过索引从0到输入数组的长度来遍历字符。
for (int i = 0; i < text.length(); i++) {
char ch = text.charAt(i);
// ...
}由于除了检索字符之外,您不使用索引,所以您只需使用toCharArray()并直接对字符进行循环:
for (char ch : text.toCharArray()) {
// ...
}然后,您将根据字符的代码点追加字符。为此,你要做的就是
out.append((char) ('A' + generator.nextInt(26))); // same for 'a' and '0'您可以直接使用appendCodePoint,而不是使用这种(丑陋的)强制转换
out.appendCodePoint('A' + generator.nextInt(26));此外,混淆字符的代码路径可能会导致潜在的错误:
if (Character.isLetter(ch)) {
if (Character.isUpperCase(ch)) {
// ...
} else {
// ...
}
} else if (Character.isDigit(ch)) {
// ...
} else {
// ...
}问题是,对于不仅是大写或小写字符的字符,isLetter返回true。例如,对于按照Unicode分类为"Lo“的所有那些奇怪的角色 (以及OTHER_LETTER中的Java),它将返回true。它还将返回true for 那些机密的“Lm” (MODIFIER_LETTER in Java),如"OL CHIKI AHAD“ᱽ。例如,由于我认为,在希伯来字母"BET",ב的情况下,您不想将其视为小写(因为您的代码不是大写字母),所以您可以完全删除该检查,并拥有:
if (Character.isUpperCase(ch)) {
sb.appendCodePoint('A' + generator.nextInt(26));
} else if (Character.isLowerCase(ch)) {
sb.appendCodePoint('a' + generator.nextInt(26));
} else if (Character.isDigit(ch)) {
sb.appendCodePoint('0' + generator.nextInt(10));
} else {
sb.append(ch);
}这样,在这些分支中只会考虑大小写(上或下)的字符。但是,有很多小写字母 (和大写字母)与a-z不同,比如ῲ或ⅎ,甚至ⱙ(这显然是"GLAGOLITIC小写字母IOTATED大YUS")。在这种情况下,它们将被拉丁文小字符取代,这可能是你想要的,也可能不是你想要的。如果你真的只想混淆拉丁字母,最好用'a'和'z'来测试字符(大写字母相反)。你知道吗?这不仅仅是字母。有很多数字不是0-9,比如٨(阿拉伯文8)或᧗(New 7),甚至꧓(显然是Javanese 3)。因此,如果您只想专注于拉丁字母和罗马数字,您可以只使用
if (ch >= 'A' && ch <= 'Z') {
sb.appendCodePoint('A' + generator.nextInt(26));
} else if (ch >= 'a' && ch <= 'z') {
sb.appendCodePoint('a' + generator.nextInt(26));
} else if (ch >= '0' && ch <= '9') {
sb.appendCodePoint('0' + generator.nextInt(10));
} else {
sb.append(ch);
}最后一个问题是关于Random对象。每次执行此方法时都要创建一个。最好只创建一个每次都重复使用相同的。例如,可以有一个常量。
private static final Random RANDOM = new Random();jumbleEmoteSpeech方法在可能的情况下,您应该总是希望尽早从方法中返回。在这种情况下,如果字符串中没有引号,则可以不加更改地返回它。
StringBuilder out = new StringBuilder();
int quote1Location = emote.indexOf('"');
if (quote1Location == -1) {
out.append(emote);
} else {
// ...
}
return out.toString();你可以用更简洁的方式写这个
int quote1Location = emote.indexOf('"');
if (quote1Location == -1) {
return emote;
}
// ...这完成了两件事:
StringBuilder:我们不需要一个else部件:它用一个缩进来移动其余部分。此外,更喜欢在使用时声明变量。在本例中,您在int quote2Location;循环之前声明while:
int quote2Location;
do {
quote2Location = emote.indexOf('"', quote1Location + 1);
// ...
} while (...);相反,你可以拥有:
do {
int quote2Location = emote.indexOf('"', quote1Location + 1);
// ...
} while (...);https://codereview.stackexchange.com/questions/124577
复制相似问题