【问题标题】:Finding combinations of a HashSet of Strings查找字符串 HashSet 的组合
【发布时间】:2015-04-09 20:20:59
【问题描述】:

我有一个HashMap<String, HashSet>String 存储此人的姓名,HashSet 存储与此人为好友的人员列表。

KEY<STRING>   VALUE<HASHSET>
Dave          Steve
Steve         Dave
Bob           Dalton
Dalton        Bob, Sue
Anne          Sue
Sue           Dalton, Anne

在上述数据中,Dave 是 Steve 的朋友(第 1 行和第 2 行)。从第 4 行开始,Dalton 是 Bob 和 Sue 的朋友。但是,Bob 和 Sue 不一定是朋友。程序需要输入 Bob 和 Sue 作为好友。换句话说,Bob 应该被添加到 Sue 的朋友列表中,而 Sue 应该被添加到 Bob 的朋友列表中。但是,Dalton 的朋友列表中的人可能是无限的。我也不允许将好友列表数据存储到ArrayArrayList

我正在考虑(但尚未尝试)的一个解决方案是编辑我的read(String name1, String name2) 方法。 (注意:在我的runner类中,每当调用这个方法时,都会调用read(name1, name2)read(name2, name1) 简而言之,这个方法读入两个好友,并将好友添加到地图中.在else 块中(如果name1 已经是HashMap 中的key),我正在考虑添加代码以获取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

但是,我不知道如何编码。有什么建议吗?

【问题讨论】:

  • 因此,如果 Dalton 与 Bob、Sue 和 Dave 成为朋友,那么您希望 Bob 与 Sue 和 Dave 成为朋友,Sue 与 Bob 和 Dave 成为朋友,Dave 与 Bob 和 Sue 成为朋友(以及他们三个都是 Dalton 的朋友)?
  • @BrianJ 是的,没错
  • 您是否仅限于使用 HashMap 来定义关系?
  • @slambeth 不,我可以使用其他结构,只是不能使用Arrays/ArrayLists 来存储数据。它也不必是&lt;String, HashSet&gt;
  • 听起来很像需要某种图表,我希望有某种递归函数来添加朋友的朋友,但我没有足够的能力来制定答案。

标签: java dictionary set combinations


【解决方案1】:

您描述的第二种解决方案相当于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));
        }
    }
}

【讨论】:

    【解决方案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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-26
      • 2021-05-01
      • 2023-04-04
      • 1970-01-01
      • 2018-06-03
      • 2017-01-02
      • 2017-10-17
      • 2018-08-18
      相关资源
      最近更新 更多