我有HashMap<String, HashSet>
。 String
存储此人的姓名,HashSet
存储与该人成为朋友的人员列表。
KEY<STRING> VALUE<HASHSET>
Dave Steve
Steve Dave
Bob Dalton
Dalton Bob, Sue
Anne Sue
Sue Dalton, Anne
在上述数据中,戴夫是史蒂夫的朋友(第1和第2行)。从第4行开始,道尔顿就是鲍勃和苏的朋友。但是,鲍勃和苏不一定是朋友。该程序需要输入Bob和Sue作为朋友。换句话说,Bob应该被添加到Sue的朋友列表中,并且Sue应该被添加到Bob的朋友列表中。然而,道尔顿的朋友名单可能会有无数人。我也不允许将好友列表数据存储到Array
或ArrayList
。
我正在考虑(但尚未尝试过)的一个解决方案是编辑我的read(String name1, String name2)
方法。 (注意:在我的跑步者课程中,无论何时调用此方法,都会将其称为read(name1, name2)
和read(name2, name1)
)简而言之,此方法会读入两个友谊并添加友谊进入地图。在else
块中(如果name1
已经是key
中的HashMap
),我正在考虑添加代码以获取现有的好友列表(只有一个价值)name1
并再次致电read
。
如果您需要,这是read
方法
private Map<String, Set> friends;
// Adds two friends, name1 and name2, to the HashMap of friendships
public void read(String name1, String name2)
{
// Temporary HashSet in case a person has more than one friend
Set<String> strSet = new HashSet<String>();
if (!friends.containsKey(name1))
{
strSet.add(name2);
friends.put(name1, strSet);
}
else
{
strSet.clear();
// Set strSet to the current friendlist of name1
strSet = friends.get(name1);
strSet.add(name2);
// Make a new entry in the HashMap with name1 and the updated friend list
friends.put(name1, strSet);
}
}
另一个解决方案(脱离此主题的标题)是找到好友列表的所有可能组合。例如如果Dalton在他的朋友列表中有Bob,Sue和Dave,我可以找到一种找到双向友谊的所有可能组合的方法(记住,顺序无关紧要):
Bob Sue
Bob Dave
Sue Dave
但是,我不知道如何编码。有什么建议吗?
答案 0 :(得分:3)
您描述的第二个解决方案相当于disjoint-set data structure。你的朋友最终会陷入困境,每一组中的每个人都与该组中的其他人成为朋友而没有其他人。
实现此数据结构的棘手部分是当您发现不同组中的两个人是朋友时合并两个集合。
这是一个天真的实施:
public class DisjointFriendSet {
private final Map<String, Set<String>> personToFriends = new HashMap<>();
/**
* Includes the person themselves in their group of friends.
*
* If no friendships have been registered for this person, then returns a set
* containing just themselves.
*
* @param person
* @return
*/
public Set<String> getFriends(String person) {
if(personToFriends.containsKey(person)) {
return personToFriends.get(person);
} else {
final Set<String> result = new HashSet<>();
result.add(person);
return result;
}
}
public void addFriendship(String person1, String person2) {
final Set<String> friends1 = getFriends(person1);
final Set<String> friends2 = getFriends(person2);
if(friends1 == friends2) {
return;
} else {
personToFriends.put(person1, friends1);
friends1.addAll(friends2);
for(String person: friends2) {
personToFriends.put(person, friends1);
}
}
}
/**
*
* @return All unique friendship groups
*/
public Collection<Set<String>> getAllFriendshipGroups() {
return new HashSet<>(personToFriends.values());
}
public static void main(String[] args) {
final DisjointFriendSet disjointFriendSet = new DisjointFriendSet();
disjointFriendSet.addFriendship("Alice","Beowulf");
disjointFriendSet.addFriendship("Charity","Donald");
disjointFriendSet.addFriendship("Eduardo","Frank");
disjointFriendSet.addFriendship("Grendel","Harriet");
System.out.println("Friendship groups: "+disjointFriendSet.getAllFriendshipGroups());
System.out.println("Adding friendship between Grendel and Beowulf");
disjointFriendSet.addFriendship("Grendel","Beowulf");
System.out.println("Friendship groups: "+disjointFriendSet.getAllFriendshipGroups());
System.out.println();
for(String person: new String[]{"Alice","Beowulf","Charity","Donald","Eduardo","Frank","Grendel","Harriet","Zod"}) {
System.out.println(person+"'s friends: "+disjointFriendSet.getFriends(person));
}
}
}
答案 1 :(得分:2)
这是一种伪代码方法(我可以稍后查找Java)
假设在每次添加时,所有朋友的朋友都匹配得恰到好处。
获取两个新输入,并创建所有朋友的临时集合以及输入值。
对于临时集合中的每个值,将每个其他值添加为朋友。 (一组只应保持唯一值,但您可以明确检查是否需要)。
这可能不是最有效的解决方案(在每一步,一半的添加都是重复的),但它应该是一个起点。
Func (friend1, friend2)
tempSet = masterSet(friend1).Hashset
UNION
masterSet(friend2).Hashset
UNION
friend1, friend2
foreach (friend in tempSet)
foreach(otherFriend in tempSet - friend)
friend.AddFriend(otherFriend)
otherFriend.AddFriend(friend)