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评论115阅读模式
英文:

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?

问题

  1. public class DeviceManagement {
  2. public static List<String> Solution(List<String> ls) {
  3. Map<String, Integer> map = new LinkedHashMap<>();
  4. int counter = 1;
  5. List<String> result = new ArrayList<>();
  6. for (String str : ls) {
  7. if (map.containsKey(str)) {
  8. int frequency = map.get(str);
  9. map.put(str, frequency + 1);
  10. result.add(str + frequency);
  11. } else {
  12. map.put(str, counter);
  13. result.add(str);
  14. }
  15. }
  16. return result;
  17. }
  18. public static void main(String[] args) {
  19. List<String> ls = new ArrayList<>();
  20. ls.add("speaker");
  21. ls.add("tv");
  22. ls.add("radio");
  23. ls.add("toaster");
  24. ls.add("radio");
  25. ls.add("speaker");
  26. System.out.println(ls);
  27. System.out.println(Solution(ls));
  28. }
  29. }
英文:

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

Sample input:

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

Sample output:

  1. [&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?

  1. public class DeviceManagement {
  2. public static List&lt;String&gt; Solution(List&lt;String&gt; ls) {
  3. Map&lt;String, Integer&gt; map = new LinkedHashMap&lt;&gt;();
  4. int counter = 1;
  5. for (String str : ls) {
  6. if (map.containsKey(str)) {
  7. map.put(str, map.get(str) + 1);
  8. } else {
  9. map.put(str, counter);
  10. }
  11. }
  12. System.out.println(map);
  13. return null;
  14. }
  15. public static void main(String[] args) {
  16. List&lt;String&gt; ls = new ArrayList&lt;&gt;();
  17. ls.add(&quot;speaker&quot;);
  18. ls.add(&quot;tv&quot;);
  19. ls.add(&quot;radio&quot;);
  20. ls.add(&quot;toaster&quot;);
  21. ls.add(&quot;radio&quot;);
  22. ls.add(&quot;speaker&quot;);
  23. System.out.println(ls);
  24. System.out.println(Solution(ls));
  25. }
  26. }

答案1

得分: 0

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

  1. public static List<String> solution(List<String> ls) {
  2. Map<String, Integer> map = new HashMap<>();
  3. ls.replaceAll(element -> {
  4. if (map.containsKey(element)) {
  5. int oldAmount = map.put(element, map.get(element) + 1);
  6. return element + oldAmount;
  7. } else {
  8. map.put(element, 1);
  9. return element;
  10. }
  11. });
  12. return ls;
  13. }

这将使您的输出为:

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

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

  1. public static List<String> solution(List<String> ls) {
  2. Map<String, Integer> map = new HashMap<>();
  3. ls.replaceAll(element -> {
  4. int newValue = map.merge(element, 1, Integer::sum);
  5. return newValue == 1 ? element : element + (newValue - 1);
  6. });
  7. return ls;
  8. }

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

  1. public static List<String> solution(List<String> ls) {
  2. Map<String, Integer> map = new HashMap<>();
  3. return ls.stream().map(element -> {
  4. int newValue = map.merge(element, 1, Integer::sum);
  5. return newValue == 1 ? element : element + (newValue - 1);
  6. }).collect(Collectors.toList());
  7. }
英文:

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:

  1. public static List&lt;String&gt; solution(List&lt;String&gt; ls) {
  2. Map&lt;String, Integer&gt; map = new HashMap&lt;&gt;();
  3. ls.replaceAll(element -&gt; {
  4. if (map.containsKey(element)) {
  5. int oldAmount = map.put(element, map.get(element) + 1);
  6. return element + oldAmount;
  7. } else {
  8. map.put(element, 1);
  9. return element;
  10. }
  11. });
  12. return ls;
  13. }

This would result in your output being:

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

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

  1. public static List&lt;String&gt; solution(List&lt;String&gt; ls) {
  2. Map&lt;String, Integer&gt; map = new HashMap&lt;&gt;();
  3. ls.replaceAll(element -&gt; {
  4. int newValue = map.merge(element, 1, Integer::sum);
  5. return newValue == 1 ? element : element + (newValue - 1);
  6. });
  7. return ls;
  8. }

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

  1. public static List&lt;String&gt; solution(List&lt;String&gt; ls) {
  2. Map&lt;String, Integer&gt; map = new HashMap&lt;&gt;();
  3. return ls.stream().map(element -&gt; {
  4. int newValue = map.merge(element, 1, Integer::sum);
  5. return newValue == 1 ? element : element + (newValue - 1);
  6. }).collect(Collectors.toList());
  7. }

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:

确定