问题链接: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']);