问题链接:https://codingbat.com/prob/p238573
要求:
编写一个函数,用raw
中的单词替换code_words
中的单词,以使raw
中每个单词的第一个出现都被赋予code_words
中的第一个未分配的单词。 / p>
encoder([[“ a”],[“ 1”,“ 2”,“ 3”,“ 4”])→[“ 1”]
encoder([[“ a”,“ b”],[“ 1”,“ 2”,“ 3”,“ 4”])→[“” 1,“ 2”]
encoder([[“ a”,“ b”,“ a”],[“ 1”,“ 2”,“ 3”,“ 4”])→[“ 1”,“ 2”,“ 1” ]
我尝试了两种不同的解决方案,但仍然表明我的功能不适用于“其他测试”
第一:
public String[] encoder(String[] raw, String[] code_words) {
HashMap<String, String> hm = new HashMap<String, String>();
for (int i=raw.length - 1; i >= 0; i--) {
hm.put(raw[i], code_words[i]);
}
String [] finalarray = new String[raw.length];
for (int i=0; i < raw.length; i++) {
String x = hm.get(raw[i]);
finalarray[i] = x;
}
return finalarray;
}
所有测试都很好,但是“其他测试”失败了
所以我认为是因为需求中的这一行
中的第一个 未分配 单词raw
中每个单词的第一次出现会被分配code_words
所以我将代码更新为:
public String[] encoder(String[] raw, String[] code_words) {
HashMap<String, String> hm = new HashMap<String, String>();
for (int i=0; i < raw.length; i++) {
String word = raw[i];
String value = code_words[i];
if (!hm.containsKey(word)) {
if (hm.containsValue(value)) {
for (int i1=0; i1 < code_words.length; i1++) {
value = code_words[i1];
if (!hm.containsValue(value)) {
hm.put(word, value);
break;
}
}
}
else {
hm.put(word, value);
}
}
}
String[] finalarray = new String[raw.length];
for (int i=0; i < raw.length; i++) {
String x = hm.get(raw[i]);
finalarray[i] = x;
}
return finalarray;
}
但是它失败了,我不知道为什么。
编辑: 我的(第二个)代码的问题是: 如果我们假设raw = {“ a”,“ a”,“ b”,“ d”} 和代码字= {“ 1”,“ 2”,“ 3”,“ 4”}
我的代码会将字母“ a”分配给“ 1”,将“ b”分配给“ 3”,将d分配给“ 4” 即使它是第一个未分配的字母,也会留下“ 2”个未分配的字母
我提供的代码经过少量调整
public String[] encoder(String[] raw, String[] code_words) {
HashMap<String, String> hm = new HashMap<String, String>();
for (int i=0; i < raw.length; i++) {
String word = raw[i];
int assigned = 0;
String value = code_words[assigned];
if (!hm.containsKey(word)) {
if (hm.containsValue(value)) {
for (int i1=0; i1 < code_words.length; i1++) {
value = code_words[i1];
if (!hm.containsValue(value)) {
hm.put(word, value);
assigned++;
break;
}
}
}
else {
hm.put(word, value);
assigned++;
}
}
}
String[] finalarray = new String[raw.length];
for (int i=0; i < raw.length; i++) {
String x = hm.get(raw[i]);
finalarray[i] = x;
}
return finalarray;
}
,但是使用下面提供的代码绝对有效。感谢贡献者!
答案 0 :(得分:1)
您正在使它变得更加复杂。
是的,您需要hm
地图,是的,仅当raw
单词在地图中尚未成为键时,才添加它。
但是要跟踪下一个未分配的code_word
,您需要的是在code_words
数组中的 index 。
Map<String, String> hm = new HashMap<>();
int unassigned = 0;
for (String word : raw) {
if (! hm.containsKey(word)) {
hm.put(word, code_words[unassigned]);
unassigned++;
}
}
整个方法的代码可以压缩为:
public String[] encoder(String[] raw, String[] code_words) {
String[] encoded = new String[raw.length];
Map<String, String> hm = new HashMap<>();
for (int i = 0, unassigned = 0; i < raw.length; i++)
if ((encoded[i] = hm.get(raw[i])) == null)
hm.put(raw[i], encoded[i] = code_words[unassigned++]);
return encoded;
}
答案 1 :(得分:1)
您的第一个想法并不是很糟糕。问题是,您应该将raw
中出现的单词的所有所有替换为code_words
中第一个未分配的单词。
首先让我们分析一下如何解决您的第一个代码。您使用HashMap的想法非常好。显然,如果HashMap中已经存在raw
一词,则您不想再次添加它,因此只需在第一次迭代中将其跳过即可。
现在,如果raw
中的第 i 个单词在HashMap中没有分配的值,则应将其添加到code_words
的第一个未分配的单词中,该单词的索引可能不同于i,因此我们为其分配了另一个索引,比方说j。之后,已经分配了第 j 个单词,而第一个未分配的单词的索引为j + 1。
像这样raw
进行一次迭代之后,每个单词在HashMap中都有一个已分配的代码,您可以再对其进行一次迭代并分配值。
您的最终代码将如下所示:
public String[] encoder(String[] raw, String[] code_words) {
HashMap<String, String> dictionary = new HashMap<>();
String[] coded = new String[raw.length];
int j = 0;
for(int i = 0; i < raw.length; i++) {
if(!dictionary.containsKey(raw[i])) { //if it has no assigned value
dictionary.put(raw[i], code_words[j]); //add to hashmap
j++; //set index to next unassigned
}
//do nothing if already found before
}
for(int i = 0; i < raw.length; i++) {
coded[i] = dictionary.get(raw[i]); //get coded word and set in final array
}
return coded;
}
我们可以编写出更加紧凑的代码,有些人可能会更喜欢,而另一些人可能会感到更困惑,所以这取决于您。
public String[] encoder(String[] raw, String[] code_words) {
HashMap<String, String> dictionary = new HashMap<>();
String[] coded = new String[raw.length];
int j = 0;
for(int i = 0; i < raw.length; i++) {
if(!dictionary.containsKey(raw[i])) { //if it has no assigned value
dictionary.put(raw[i], code_words[j++]); //add to hashmap and also increment index of code_words
}
coded[i] = dictionary.get(raw[i]);
}
return coded;
}
最后一个代码通过了所有测试。
答案 2 :(得分:1)
只需更新一行
hm.put(raw[i], code_words[raw[i].charAt(0)-'a']);