Java 将缩写/俚语替换为其完整形式
我使用HashMap存储缩写的完整表单Java 将缩写/俚语替换为其完整形式,java,string,hashmap,Java,String,Hashmap,我使用HashMap存储缩写的完整表单 public class Test { public static void main(String[] args) { Map<String, String> slangs = new HashMap<String, String>(); slangs.put("lol", "laugh out loud"); slangs.put("r", " are ");
public class Test {
public static void main(String[] args) {
Map<String, String> slangs = new HashMap<String, String>();
slangs.put("lol", "laugh out loud");
slangs.put("r", " are ");
slangs.put("n", " and ");
slangs.put("idk", " I don't know ");
slangs.put("u", " you ");
Set set = slangs.entrySet();
Iterator i = set.iterator();
String sentence = "lol how are you";
StringBuilder sb = new StringBuilder();
for (String word : sentence.split(" ")) {
while(i.hasNext()) {
Map.Entry<String, String> me = (Map.Entry)i.next();
if (word.equalsIgnoreCase(me.getKey())) {
sb.append(me.getValue());
continue;
}
sb.append(word);
}
}
System.out.println(sb.toString());
}
}
这里有什么问题,我该如何解决?您不应该迭代条目以找到匹配项,您应该使用或获取给定缩写的完整形式,否则,您将使用
O(n)而不是时间复杂度为O(1)
的完整形式来获取它
当然,这在性能方面并不好,但您将失去在映射中拥有键/值对的真正好处。如果您是因为大小写而这样做的,只需将键放在地图中的小写字母中,然后调用get
或getOrDefault
,使用小写字母如下:
所以你的循环应该是这样的:
for (String word : sentence.split(" ")) {
// Get the full form of the value of word in lower case otherwise use
// the word itself
sb.append(slangs.getOrDefault(word.toLowerCase(), String.format(" %s", word)));
}
输出:
laugh out loud how are you
使用,它可以是:
String result = Pattern.compile(" ")
.splitAsStream(sentence)
.map(word -> slangs.getOrDefault(word.toLowerCase(), word))
.collect(Collectors.joining(" "));
简单地说,我认为您只需要检查俚语
是否包含此关键字。
请检查我的密码
public class Test {
public static void main(String[] args) {
Map<String, String> slangs = new HashMap<String, String>();
slangs.put("lol", "laugh out loud");
slangs.put("r", " are ");
slangs.put("n", " and ");
slangs.put("idk", " I don't know ");
slangs.put("u", " you ");
String sentence = "lol how are you";
String[] words = sentence.split(" ");
for (String word : words) {
String normalizeWord = word.trim().toLowerCase();
if(slangs.containsKey(normalizeWord)) {
sentence = sentence.replace(word, slangs.get(normalizeWord));
}
}
System.out.println(sentence);
}
}
公共类测试{
公共静态void main(字符串[]args){
Map slags=newhashmap();
俚语。放(“lol”,“大声笑”);
俚语。put(“r”,“are”);
俚语。把(“n”,“and”);
俚语;
俚语。把(“u”、“你”);
String-sense=“lol你好吗”;
字符串[]单词=句子。拆分(“”);
for(字符串字:字){
字符串normalizeWord=word.trim().toLowerCase();
if(俚语containsKey(normalizeWord)){
句子=句子.替换(单词,俚语.get(normalizeWord));
}
}
System.out.println(句子);
}
}
不要在字典中的键上循环。相反,只需检查键是否在映射中并获得相应的值。另外,别忘了在组合句中加上空格
for (String word : sentence.split(" ")) {
if (slangs.containsKey(word.toLowerCase())) {
sb.append(slangs.get(word.toLowerCase()));
} else {
sb.append(word);
}
sb.append(" ");
}
如果您使用的是Java 8,还可以使用String.join
、Map.getOrDefault
和Streams:
String s = String.join(" ", Stream.of(sentence.split(" "))
.map(word -> slangs.getOrDefault(word.toLowerCase(), word))
.toArray(n -> new String[n]));
后一种方法还有一个好处,就是在句子的第一个单词之前或最后一个单词之后不加空格。Idk为什么要把它弄得很复杂。我的第一个想法是,把句子分成几个单词,然后检查俚语是否包含它。你想要得到什么结果?输出应该是:“大笑,你好吗”@Mahn,但我该怎么做?试着打印所有结果,我不确定你为什么要使用它,而(i.hasNext())首先,你的句子不起作用,因为你是逐字逐句的,这意味着,例如在lol的情况下,你的句子中有俚语,而不是短语本身。我认为您应该检查internet上的一些解决方案,并以此为基础。containsKey()
是多余的,如果您要调用get()
。和replaceAll()
可能会在正则表达式特殊字符上失败。如果要使用replaceAll()
@shmosel,那么迭代单词而不是条目似乎有点倒退-我发现containsKey+的用法比直接访问var、测试var是否为null、然后使用更容易阅读。是的,效率稍低,但不应明显。我同意迭代顺序;这是一个更加明显的问题inefficiency@shmosel谢谢你的评论。我们同意,因为要遍历句子,所以应该使用replace
。将更新我的答案。我认为如果不使用containsKey()
,我们需要使用一些临时变量,如StringBuilder来获得正确答案。您应该使用word.toLowerCase()
进行查找。另外,您可以使用String[]::new
而不是n->new String[n]
@shmosel,这两点都是一致的。奇怪的是,String[]::new
在Eclipse中给了我奇怪的编译问题,所以无法测试,只更改了第一个。
for (String word : sentence.split(" ")) {
if (slangs.containsKey(word.toLowerCase())) {
sb.append(slangs.get(word.toLowerCase()));
} else {
sb.append(word);
}
sb.append(" ");
}