如何解决这个CodingBat编码器问题



问题链接:https://codingbat.com/prob/p238573

要求:编写一个函数,将raw中的单词替换为code_words中的单词,以便为raw中每个单词的第一次出现分配code_words中第一个未分配的单词。

编码器(["a"]、["1"、"2"、"3"、"4"](→["1"]

编码器(["a","b"],["1","2","3","4"](→["1"、"2"]

编码器(["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为"0";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;
}

但使用下面提供的代码肯定更有效。感谢贡献者!

问题

你的第一个想法并没有那么糟糕。问题是,您应该用code_words中第一个未分配的单词替换raw中出现的所有单词。

如何修复

让我们首先分析如何修复您的第一个代码。您使用HashMap的想法非常好。很明显,如果一个raw的单词已经存在于HashMap中,您不想再添加它,所以您只需在第一次迭代中跳过它
现在,如果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;
}

最后一个代码通过了所有测试。

你让它变得比现在复杂得多。

是的,你需要hm映射,是的,只有当raw单词还不是映射中的键时,你才能添加到它中。

但是,要跟踪下一个未分配的code_word,您只需要在code_words数组中创建索引

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;
}

只需更新一行

hm.put(raw[i], code_words[raw[i].charAt(0)-'a']);

最新更新