【问题标题】:How to solve this CodingBat encoder problem?如何解决这个 CodingBat 编码器问题?
【发布时间】:2020-11-07 23:19:32
【问题描述】:

问题链接: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 中的第一个 unassigned 单词

所以我将代码更新为:

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

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

【问题讨论】:

    标签: java methods encode


    【解决方案1】:

    问题

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

    如何解决

    让我们首先分析如何修复您的第一个代码。您使用 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;
    }
    

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

    【讨论】:

    • 您好,非常感谢。我明白了这一点,但我在我的代码中想到了这一点,所以当我的代码与一个赋值交叉时,它从 code_words(第 8 行)处的索引 0 开始并再次检查整个数组。当然你的代码似乎更有效率,但我不知道是什么导致我的代码失败
    • nvm,我想通了
    【解决方案2】:

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

    是的,您需要 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;
    }
    

    【讨论】:

    • 哇!我真的希望我能批准 2 个答案:D 这非常有帮助,非常感谢。但如果可能的话,你能告诉我为什么我在第 8 行创建的循环不能作为你函数中未分配的变量工作吗?当然你的效率更高,但我只需要了解失败的原因
    • nvm,我想通了
    【解决方案3】:

    只更新一行

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-06
      • 2020-07-25
      • 2013-04-21
      • 1970-01-01
      • 2018-05-11
      • 1970-01-01
      相关资源
      最近更新 更多