我想要一个翻译例程,它允许我有效地将任何字符翻译成任何其他字符或字符集。显而易见的方法似乎是使用输入字符串中的字符值作为256项转换数组的索引。
给定一个初始数组,其中每个条目都设置为其值,例如hex'37'将出现在第56个条目中(允许00成为第一个),然后用户可以替换翻译字符串中所需的任何字符。
例如我想用字母字符“A”映射字符串,数字字符用“N”,空格字符用“B”,其他任何东西用“X”映射。因此,“SL5 3QW”成为“AANBNAA”。
e.g.2。我想翻译一些字符,例如“œ”(x'9D')到“oe”(x'6F65'),“ß”到“ss”,“å”到“a”等等。
如何从输入字符串中的字符获取数值以将其用作translate数组的索引?
在Excel中使用CODE功能很简单,在IBM汇编程序中很简单,但是我无法在Java中找到一个方法。
答案 0 :(得分:5)
这有点偏离主题,但如果您想要进行全面的字符翻译工作,则不能简单地使用String.charAt(int)
。大于65535的Unicode代码点在Java字符串中表示为两个连续的char
值。
处理此问题的干净方法是使用String.codepointAt(int)
提取每个代码点,并String.offsetByCodePoints(int, int)
逐步执行代码点位置。
答案 1 :(得分:3)
最新版本的Unicode包含超过107000个字符。 256条转换数组不会削减它。
也就是说,您可以使用String.codepointAt(int index)
方法在字符串中的索引处获取代码点。
您可能还想使用Character.isWhitespace(int codepoint)
和Character.isDigit(int codepoint)
等等。
另请参阅http://download.oracle.com/javase/6/docs/api/java/lang/String.html和http://download.oracle.com/javase/6/docs/api/java/lang/Character.html
答案 2 :(得分:2)
HashMap<String, String>
应该工作得很好。无需过度设计这样一个简单的问题。
答案 3 :(得分:1)
正如Christoffer所说,使用Unicode字符时,256个元素的数组是不够的。
一种方法是使用HashMap<Character,String>
将每个字符映射到所需的翻译值,并使用String.charAt()
依次提取每个字符。您还可以查看Character类的一些方法,如isDigit()
和isLetter()
来完成一些工作;这可能比为每个“字母”构建一个映射更容易(可能是多种语言)。
通过使用HashMap,您只需要为要翻译的字符定义映射。对于没有映射的(hashmap返回null),您可以指定默认值或将其传递给未更改。
答案 4 :(得分:1)
有不同的方法来回答这个问题。最简单的方法可能是为每个问题单独提出答案:
例如我想用“A”映射一个字符串 对于字母字符,“N”表示 数字字符,空格“B” 其他任何字符和“X”。 因此,“SL5 3QW”成为“AANBNAA”。
简单解决方案:
public static String map(final String input){
final char[] out = new char[input.length()];
for(int i = 0; i < input.length(); i++){
final char c = input.charAt(i);
final char t;
if(Character.isDigit(c)){
t = 'N';
} else if(Character.isWhitespace(c)){
t = 'B';
} else if(Character.isLetter(c)){
t = 'A';
} else{
t = 'X';
}
out[i] = t;
}
return new String(out);
}
<强>测试强>
public static void main(final String[] args){
System.out.println(map("SL5 3QW"));
}
<强>输出:强>
AANBNAA
e.g.2。我想翻译一些 字符,例如“œ”(x'9D') “oe”(x'6F65'),“ß”到“ss”,“å”到 “a”等。
<强>解决方案:强>
这是标准功能,您应该使用Normalizer API。请参阅these previous个答案以供参考。
但第二个想法当然有一个更普遍的解决方案来解决你的问题。让我们来看看if / else爱好者为此获得了多少次downvotes。定义变换器的接口,该接口接受某些字符和/或字符类,并将它们映射到其他字符:
public interface CharTransformer{
boolean supports(char input);
char transform(char input);
}
现在定义一个方法,您可以使用字符串和此类变换器的集合进行调用。对于每个单个字符,将查询每个变换器以查看他是否支持该字符。如果他这样做,让他做转变。如果没有找到字符的Transformer,则抛出异常。
public static String mapWithTransformers(final String input,
final Collection<? extends CharTransformer> transformers){
final char[] out = new char[input.length()];
for(int i = 0; i < input.length(); i++){
final char c = input.charAt(i);
char t = 0;
boolean matched = false;
for(final CharTransformer tr : transformers){
if(tr.supports(c)){
matched = true;
t = tr.transform(c);
break;
}
}
if(!matched){
throw new IllegalArgumentException("Found no Transformer for char: "
+ c);
}
out[i] = t;
}
return new String(out);
}
注意:其他人建议使用地图。虽然我认为标准地图不适合此任务,但您可以使用Guava的MapMaker.makeComputingMap(function)根据需要计算替换(并自动缓存它们)。这样你就有了一个懒惰的初始化缓存地图。