假设我有一对元素列表,如(1,2)(3,4),其中不存在重复项,对于一对(p,q)p!= q。 如何使用简单的代码从这些元素形成一个集合(我不打算使用像脱节集和联合这样的数据结构,而是使用java库API - 除非代码可以用简单的方式编写)。 示例:(1,2)(2,4)(5,6)(4,7)(3,5)应输出: {1,2,4,7}和{3,5,6}
List<Set<Integer>> list = new ArrayList<>();
for(String s : pairs){
String[] values = s.split(" ");
Integer val1 = Integer.parseInt(values[0]);
Integer val2 = Integer.parseInt(values[1]);
Set<Integer> pairSet = new HashSet<>();
pairSet.add(val1);
pairSet.add(val2);
boolean exists = false;
for(Set<Integer> set : list){
if(set.contains(val1) || set.contains(val2)) {
set.addAll(pairSet);
exists = true;
break;
}
}
if(!exists)
list.add(pairSet);
}
这是一种不正确的天真方法。如果我得到一个序列(1 2)(3 4)和(2 3),那么输出变为{1,2,3}和{3,4}。
这是因为集合列表的创建方式如下: {1,2}然后{3,4}然后当对(2 3)到来时,它不会合并2组。
我可以编写一个代码来检查第一个值是否出现在任何一个集合中,然后说S1,然后对另一个值表示S2然后合并:
//loop -> s1 = find val1
//loop -> s2 = find val2
if s1 != null and s2 != null //merge s1 and s2
if(s1 == null && s2 != null) //add val1 and val2 to s2
if(s1 != null && s2 == null) //add val1 and val2 to s1
if(both null) create a new set of val1 and val2
循环和条件太多。任何更简单的解决方案?
答案 0 :(得分:0)
修订版:
在这里,我使用了你所谓的朴素方法:
public static List<Set<Integer>> answer(String[] pairs){
List<Set<Integer>> list = new LinkedList<>();
// For each pair, separate the numbers
//Initialize with initial set
Set<Integer> init = new HashSet<>();
String[] splitted = pairs[0].split(" ");
init.add(Integer.parseInt(splitted[0]));
init.add(Integer.parseInt(splitted[1]));
list.add(init);
// To be used to maintain set record ahead
List<Set<Integer>> setsRecord = new LinkedList<>();
boolean found = false;
Integer i1, i2;
for(String s : pairs){
i1 = Integer.parseInt((splitted = s.split(" "))[0]);
i2 = i2 = Integer.parseInt(splitted[1]);
for(Set<Integer> set : list){
if(set.contains(i1) || set.contains(i2)){
// If element has already been found in a set, create a common set
if(setsRecord.size() >= 1){
setsRecord.get(0).addAll(set);
// And remove this set
list.remove(set);
}
else{
set.add(i1);
set.add(i2);
// Maintain a record of this set
setsRecord.add(set);
}
found = true;
}
}
// Empty the temporary set record
setsRecord.clear();
if(!found){
Set<Integer> newSet = new HashSet<Integer>();
newSet.add(i1);
newSet.add(i2);
list.add(newSet);
}
found = false;
}
return list;
}
答案 1 :(得分:0)
我正在发布解决方案。如果有人可以使这个代码更简单,那就太棒了。 TIA
static void formSet(String[] pairs) {
List<Set<Integer>> list = new ArrayList<>();
for(String s : pairs){
String[] values = s.split(" ");
Integer val1 = Integer.parseInt(values[0]);
Integer val2 = Integer.parseInt(values[1]);
Set<Integer> pairSet = new HashSet<>();
pairSet.add(val1);
pairSet.add(val2);
Set<Integer> val1_set = null, val2_set = null;
for(Set<Integer> set : list){
if(set.contains(val1)) {
val1_set = set;
}
if(set.contains(val2)) {
val2_set = set;
}
}
if(val1_set == null && val2_set == null)
list.add(pairSet);
if(val1_set != null && val2_set == null)
val1_set.addAll(pairSet);
if(val1_set == null && val2_set != null)
val2_set.addAll(pairSet);
if(val1_set != null && val2_set != null){
list.remove(val2_set);
val1_set.addAll(val2_set);
}
}
for(Set<Integer> set : list){
System.out.println(set);
}
}
这里是codereview的链接: https://codereview.stackexchange.com/questions/163301/forming-a-set-from-a-pair-of-numbers
答案 2 :(得分:-1)
如果您将每对视为图形边缘的描述,那么简单的DFS就可以解决问题。
import java.util.*;
import java.lang.*;
import java.io.*;
class Solution
{
static int n = 1000000;
static ArrayList< ArrayList<Integer> > adj = new ArrayList<ArrayList<Integer>>();
static Boolean[] visited = new Boolean[n];
public static void main (String[] args) throws java.lang.Exception
{
String input[] = {"1 2", "3 4", "2 3","5 6"};
System.out.println(answer(input));
}
public static void dfs(int u,Set<Integer> res){
visited[u] = true;
for(int e : adj.get(u)){
if(!visited[e])
dfs(e,res);
}
res.add(u);
}
static void init(){
for(int i = 0 ; i < n ; i++)
adj.add(new ArrayList<Integer>());
}
public static List<Set<Integer>> answer(String[] pairs){
init();
List<Set<Integer>> list = new LinkedList<>();
Set<Integer> elements = new HashSet<Integer>();
for(int i = 0 ; i < pairs.length ; i++){
String[] splitted = pairs[i].split(" ");
int u = Integer.parseInt(splitted[0]);
int v = Integer.parseInt(splitted[1]);
adj.get(u).add(v);
adj.get(v).add(u);
visited[u] = visited[v] = false;
elements.add(u);elements.add(v);
}
for(int e : elements){
if(!visited[e]){
Set<Integer> tmp = new HashSet<Integer>();
dfs(e,tmp);
list.add(tmp);
}
}
return list;
}
}