Counting the number of elements in a List and appending it to the end of each item and maintaining insertion order in list to be returned?

huangapple go评论83阅读模式
英文:

Counting the number of elements in a List and appending it to the end of each item and maintaining insertion order in list to be returned?

问题

public class DeviceManagement {
    public static List<String> Solution(List<String> ls) {
        Map<String, Integer> map = new LinkedHashMap<>();
        int counter = 1;

        List<String> result = new ArrayList<>();
        for (String str : ls) {
            if (map.containsKey(str)) {
                int frequency = map.get(str);
                map.put(str, frequency + 1);
                result.add(str + frequency);
            } else {
                map.put(str, counter);
                result.add(str);
            }
        }

        return result;
    }

    public static void main(String[] args) {
        List<String> ls = new ArrayList<>();
        ls.add("speaker");
        ls.add("tv");
        ls.add("radio");
        ls.add("toaster");
        ls.add("radio");
        ls.add("speaker");
        System.out.println(ls);
        System.out.println(Solution(ls));
    }
}
英文:

I am working on a problem and needed some possible approaches to it.

Sample input:

[&quot;tv&quot;, &quot;speaker&quot;, &quot;tv&quot;, &quot;radio&quot;, &quot;radio&quot;, &quot;tv&quot;]

Sample output:

[&quot;tv&quot;, &quot;speaker&quot;, &quot;tv1&quot;, &quot;radio&quot;, &quot;radio1&quot;, &quot;tv2&quot;]

Add the number of occurrences while leaving the first occurrence as it is.

So far I have added the elements to a HashMap and using Collection.frequency/get put for the element count to count the number of elements. However, what would be a way to append the corresponding number at the end?

public class DeviceManagement {
    public static List&lt;String&gt; Solution(List&lt;String&gt; ls) {
	    Map&lt;String, Integer&gt; map = new LinkedHashMap&lt;&gt;();
	    int counter = 1;
	 
        for (String str : ls) {
		    if (map.containsKey(str)) {
			    map.put(str, map.get(str) + 1);
		    } else {
                map.put(str, counter);
            }
	    }
	    
        System.out.println(map);
	    return null;
    }

    public static void main(String[] args) {
	    List&lt;String&gt; ls = new ArrayList&lt;&gt;();
	    ls.add(&quot;speaker&quot;);
	    ls.add(&quot;tv&quot;);
	    ls.add(&quot;radio&quot;);
	    ls.add(&quot;toaster&quot;);
	    ls.add(&quot;radio&quot;);
	    ls.add(&quot;speaker&quot;);
	    System.out.println(ls);
	    System.out.println(Solution(ls));
    }
}

答案1

得分: 0

您的代码正确地检测出重复项并计算频率,但在迭代过程中未替换 List 中的任何元素为其新值。为了简化此过程,我建议使用 List#replaceAll 替代 for 循环。您的代码将类似于以下内容:

public static List<String> solution(List<String> ls) {
    Map<String, Integer> map = new HashMap<>();

    ls.replaceAll(element -> {
        if (map.containsKey(element)) {
            int oldAmount = map.put(element, map.get(element) + 1);
            return element + oldAmount;
        } else {
            map.put(element, 1);
            return element;
        }
    });

    return ls;
}

这将使您的输出为:

[speaker, tv, radio, toaster, radio1, speaker1]

为了稍微简化代码,您可以使用 Map#merge

public static List<String> solution(List<String> ls) {
    Map<String, Integer> map = new HashMap<>();

    ls.replaceAll(element -> {
        int newValue = map.merge(element, 1, Integer::sum);
        return newValue == 1 ? element : element + (newValue - 1);
    });

    return ls;
}

如果您想返回另一个不同的 List 对象,您可以对输入进行流式处理,映射它,并将其收集到另一个 List 中:

public static List<String> solution(List<String> ls) {
    Map<String, Integer> map = new HashMap<>();

    return ls.stream().map(element -> {
        int newValue = map.merge(element, 1, Integer::sum);
        return newValue == 1 ? element : element + (newValue - 1);
    }).collect(Collectors.toList());
}
英文:

Your code correctly detects duplicates and counts frequencies, but doesn't replace any elements in the List with their new values while you're iterating over it. To make this easy, I recommend using List#replaceAll instead of a for-loop. Your code would look something like:

public static List&lt;String&gt; solution(List&lt;String&gt; ls) {
    Map&lt;String, Integer&gt; map = new HashMap&lt;&gt;();

    ls.replaceAll(element -&gt; {
        if (map.containsKey(element)) {
            int oldAmount = map.put(element, map.get(element) + 1);
            return element + oldAmount;
        } else {
            map.put(element, 1);
            return element;
        }
    });

    return ls;
}

This would result in your output being:

[speaker, tv, radio, toaster, radio1, speaker1]

To simplify your code a bit, you can utilize Map#merge:

public static List&lt;String&gt; solution(List&lt;String&gt; ls) {
    Map&lt;String, Integer&gt; map = new HashMap&lt;&gt;();

    ls.replaceAll(element -&gt; {
        int newValue = map.merge(element, 1, Integer::sum);
        return newValue == 1 ? element : element + (newValue - 1);
    });

    return ls;
}

If you want to return a different List object, then you can stream your input, map it, and collect it to another List:

public static List&lt;String&gt; solution(List&lt;String&gt; ls) {
    Map&lt;String, Integer&gt; map = new HashMap&lt;&gt;();

    return ls.stream().map(element -&gt; {
        int newValue = map.merge(element, 1, Integer::sum);
        return newValue == 1 ? element : element + (newValue - 1);
    }).collect(Collectors.toList());
}

huangapple
  • 本文由 发表于 2020年3月15日 09:39:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/60688954.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定