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());
}
我对编程有点陌生,并且很难完成这项任务。我有一个 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());
}