Java 在数组中查找重复的字符串并添加相应的 int 值

Java finding duplicate stings in array and adding corresponding int values

我对编程有点陌生,并且很难完成这项任务。我有一个 table 名称(字符串)和相应的值(int)。现在我正在查找名称中的重复项,如果该名称已存在于 table.

中,则将 int 值相加

我对如何做到这一点有一个模糊的想法,但我也很确定这不是解决问题的理想方法。我正在尝试优化我得到的结果。我的想法是使用 2 个数组,一个用于名称,一个用于数字,如果数组中有重复的名称,我将转到数字数组中的相同位置并添加相应的数字。 我最初的想法是这样的:

String[] names = {a,b,a,a,c,b};
Integer[] numbers = {5,2,3,1,2,1};

for (int i = 0; i < names.length; i++) {
    for (int j = i + 1; j < names.length; j++) {
        if (names[i].equals(names[j]) ) {
           numbers[i] += numbers[j]
        } System.out.println("Name: " + names[i] + " Amount: " + numbers[i])
    }
}

预期的输出应该是这样的: a = 10 b = 3 c = 1

我知道这是一种蛮力方法,但我需要知道数组中的位置才能起作用。我没有使用树图的经验,但这可能是解决手头问题的更简单方法。谢谢你的帮助。

您可以使用地图界面。 使用您的字符串数组 "names" 作为键。为它和里面写一个for循环: 如果您的地图包含键,则获取值并与新值相加。

PS: 暂时不会写代码,以后再更新

您可以使用Treemap 来包含您输入的String 对应的口是心非和总和。同样使用树图,如果需要,您的输出将采用排序格式。

public static void main(String[] args) {

  String[] names = {"a","b","a","a","c","b"};
  Integer[] numbers = {5,2,3,1,2,1};
  Map<String, Integer> map = new TreeMap<>();

  for (int i = 0; i < names.length; i++) {
    if (!map.containsKey(names[i])) {
      map.put(names[i], 0);
    }
    map.put(names[i], map.get(names[i]) + numbers[i]);
  }

  for (String key : map.keySet()) {
    System.out.println( key +" = " + map.get(key));
  }
}

以上代码的输出将是(如@vincrichaud 所指出的):

a = 9
b = 3
c = 2

我已经在评论中建议了:你可以使用地图来统计所有的值。
这是一个故意冗长的示例(以说明发生了什么):

    String[] names = {"a","b","a","a","c","b"};
    Integer[] numbers = {5,2,3,1,2,1};

    Map<String, Integer> totals = new HashMap<String, Integer>(); 

    for (int i = 0; i < names.length; i++) {
        if (totals.containsKey(names[i])) {
            totals.put(names[i], totals.get(names[i]) + numbers[i]);
        } else {
            totals.put(names[i], numbers[i]);
        }
    }

    System.out.println(totals);

因此,如果该名称已在地图中,只需将计数增加新的数字即可。如果不是,请添加带有编号的新地图条目。
请注意,要使其正常工作,您的两个数组的长度必须相等!

这将打印:

{a=9, b=3, c=2}

这是一个工作示例:

import java.util.HashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        String[] names = {"a","b","a","a","c","b"};
        Integer[] numbers = {5,2,3,1,2,1};

        Map<String, Integer> occurrences = new HashMap<>();
        for(int i = 0; i < names.length; ++i) {
            String key = names[i];
            Integer previousNumber = occurrences.getOrDefault(key, 0);  //Previously stored number
            Integer correspondingNumber = numbers[i];   //Delta for specified name
            occurrences.put(key, previousNumber + correspondingNumber); //Storing new value
        }

        //Print result
        occurrences.forEach((key, value) -> System.out.println("Name: " + key + " Amount: " + value));
    }
}

Maps 允许您将某种值分配给某个唯一键。 一般来说,Map 的 put/retrieval 操作据说具有 O(1) 时间复杂度,这使它们成为您问题的完美解决方案。 最基本的实现是HashMap,但是如果你想在迭代时保持名称的顺序,就使用LinkedHashMap。 另一方面,如果您希望您的数据以某种方式排序,那么您很可能会使用 TreeMap。

编辑: 就像下面评论部分提到的 Sharon Ben Asher 一样,您可以使用 merge() 方法来缩短代码:

import java.util.HashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        String[] names = {"a","b","a","a","c","b"};
        Integer[] numbers = {5,2,3,1,2,1};

        Map<String, Integer> occurrences = new HashMap<>();
        for(int i = 0; i < names.length; ++i)
            occurrences.merge(names[i], numbers[i], Integer::sum);

        //Print result
        occurrences.forEach((key, value) -> System.out.println("Name: " + key + " Amount: " + value));
    }
}

但我在第一个答案中将其分解了一些,只是为了让您更好地解释地图的工作原理。基本上你使用像 get() 这样的方法(getOrDefault() 是它的一个变体,即使没有找到给定键的映射,它的 returns 值)和 put() 允许你提交新的 mapping/override 现有对于给定的密钥。

使用地图就可以满足您的要求。可以按如下方式完成

String[] 名称 = {"a", "b", "a", "a", "c", "b"};

整数[] 数字 = {5, 2, 3, 1, 2, 1};

Map expectedOut = new HashMap();

for (int i = 0; i < names.length; i++) {
  if (expectedOut.containsKey(names[i]))
    expectedOut.put(names[i], expectedOut.get(names[i]) + numbers[i]);
  else
    expectedOut.put(names[i], numbers[i]);
}

for (Map.Entry<String, Integer> out : expectedOut.entrySet())
  System.out.println(out.getKey() + " = " + out.getValue());

}