我有一个结构如下的数组:
String Array = {"1","2","3","41","56","41","72","72","72","78","99"}
我希望将这个数组分成多个数组,这些数组的值不重复......就像这样:
String Array1 = {"1","2","3","41","56","72","78","99"}
String Array2 = {"41","72"}
String Array3 = {"72"}
有没有直接的方法在Java中执行此操作,或者我必须使用丑陋的循环执行此操作(开玩笑!)?
谢谢!
更新
我会让问题变得更难......现在我有一张地图,结构如下:
Map<String,String> map = new HashMap(){{
put("1@@96","10");
put("2@@100","5");
put("3@@23","100");
put("41@@34","14");
put("56@@22","25");
put("41@@12","100");
put("72@@10","100");
put("72@@100","120");
put("72@@21","0");
put("78@@22","7");
}}
请注意,这些值并不重要但是键很重要...... 我该怎么做才能将这个地图划分为子图,如:
Map map1 = {"1@@96" => "10"
"2@@100" => "5"
"3@@23" => "100"
"41@@34" => "14"
"56@@22" => "25"
"72@@10" => "100"
"78@@22" => "7"
}
Map map2 = {
"41@@12" => "100"
"72@@100" => "120"
}
Map map3 = {
"72@@100" => "120"
}
在地图的第一部分之前(在&#39; @@&#39;之前)是我希望唯一性基于的ID ...这就像数组示例但更难一点更复杂......
很抱歉中途改变了问题...
答案 0 :(得分:2)
libs中可能没什么(似乎不够通用)但是有些想法:
O(n)时间和O(n)空间复杂度。在这里,您只需计算每个数字出现的次数,然后将它们放入多个结果数组中。
@Edit:正如@mpkorstanje指出的那样,如果你将数字输入更改为字符串或在最糟糕的情况下任何其他对象,这将降级为O(n ^ 2)。但在这种情况下,你应该修改你正在工作的数据的哈希imho,因为它没有很好地分发。
public List<List<Integer>> split(int[] input) {
Map<Integer, Integer> occurrences = new HashMap<>();
int maxOcc = 0;
for (int val : input) {
int occ = 0;
if (occurrences.containsKey(val)) {
occ = occurrences.get(val);
}
if (occ + 1 > maxOcc) {
maxOcc = occ + 1;
}
occurrences.put(val, occ + 1);
}
List<List<Integer>> result = new ArrayList<>(maxOcc);
for (int i = 0; i < maxOcc; i++) {
result.add(new LinkedList<>());
}
for (Map.Entry<Integer, Integer> entry : occurrences.entrySet()) {
for (int i = 0; i < entry.getValue(); i++) {
result.get(i).add(entry.getKey());
}
}
return result;
}
O(nlogn)时间和O(1)空间复杂度(不计算结果数组)但不保留顺序并“破坏”输入数组。在这里,您可以利用数组已经排序的事实,这样您就可以查看它并继续将元素添加到适当的结果列表中,具体取决于您是在查看重复条目还是“新”条目。
public List<List<Integer>> split(int[] input) {
Arrays.sort(input);
int maxDup = getMaxDuplicateNumber(input);
List<List<Integer>> result = new ArrayList<>(maxDup);
for(int i = 0; i < maxDup; i++) {
result.add(new LinkedList<>());
}
int count = 0;
result.get(0).add(input[0]);
for(int i = 1; i < input.length; i++) {
if(input[i] == input[i-1]) {
count++;
} else {
count = 0;
}
result.get(count).add(input[i]);
}
return result;
}
private int getMaxDuplicateNumber(int[] input) {
int maxDups = 1;
int currentDupCount = 1;
for(int i = 1; i < input.length; i++) {
if(input[i] == input[i - 1]) {
currentDupCount++;
} else {
currentDupCount = 1;
}
if(currentDupCount > maxDups) {
maxDups = currentDupCount;
}
}
return maxDups;
}
答案 1 :(得分:1)
如果没有循环,你就无法做到这一点。但是您可以使用一组来删除一些循环。您可以根据自己的喜好添加数据结构陷阱。
我假设这里的元素顺序必须与输入数组中元素的顺序一致。如果不是这样可以更有效地完成。
public static void main(String[] args) {
String[] array = { "1", "2", "3", "41", "56", "41", "72", "72", "72",
"78", "99" };
List<Set<String>> bins = new ArrayList<>();
for (String s : array) {
findOrCreateBin(bins, s).add(s);
}
System.out.println(bins); // Prints [[1, 2, 3, 41, 56, 72, 78, 99], [41, 72], [72]]
}
private static Set<String> findOrCreateBin(List<Set<String>> bins, String s) {
for (Set<String> bin : bins) {
if (!bin.contains(s)) {
return bin;
}
}
Set<String> bin = new LinkedHashSet<>();
bins.add(bin);
return bin;
}