我对编程有点陌生,并为此任务而苦苦挣扎。我有一个带有名称(字符串)和对应值(int)的表。现在,我正在查找名称中的重复项,如果该名称已存在于表中,则将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
我知道这是一种蛮力方法,但是我需要知道Array中的位置才能起作用。我没有使用树状图的经验,但这可能是解决当前问题的一种更简便的方法。谢谢您的帮助。
答案 0 :(得分:0)
您可以使用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
答案 1 :(得分:0)
我已经在注释中建议了它:您可以使用地图来计算所有值。
这是一个故意冗长的示例(以明确发生的情况):
tt.GetAwaiter().GetResult();
因此,如果名称已经在地图中,则只需增加新数字即可。如果不是,请添加一个带有该编号的新地图条目。
请注意,要使它起作用,两个数组的长度必须相等!
这将打印:
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);
答案 2 :(得分:0)
这是一个有效的示例:
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));
}
}
地图允许您为某些唯一键分配某种值。 一般说来,Map的放置/检索操作的时间复杂度为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()是它的一种变体,即使未找到给定键的映射也将返回值),而put()则允许您提交给定键的新映射/重写。 / p>
答案 3 :(得分:-2)
使用地图就可以满足您的要求。可以按照以下步骤完成
String []名称= {“ a”,“ b”,“ a”,“ a”,“ c”,“ b”};
Integer []数字= {5,2,3,1,2,1};
Map Expected = 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());
}
答案 4 :(得分:-3)
您可以使用Map界面。 使用您的字符串数组“名称”作为键。为它和内部编写一个for循环: 如果您的地图包含密钥,请获取值并与新值相加。
PS:目前无法编写代码,我稍后可以更新。