在java中的相同列表中的成员之间进行配对

时间:2016-02-08 06:25:27

标签: java list dictionary arraylist logic

在问题陈述中,我有'n'个家庭成员数目很多的家庭。

例如:

John jane (family 1)
tiya (family 2)
Erika (family 3)

我必须以一种不应该与他的家人配对的方式指派所有成员。 输出应该是:

John => tiya
jane => Erika
tiya => jane
Erika => john

我创建了对象Person(name ,familyID, isAllocated)。 创建了列表并在此中添加了personName_id

我正在考虑使用地图进行关联。因此john_1将成为关键,tiya_2将成为价值。

我无法通过地图关联这些对。我怎样才能将名单上的成员洗牌。

此外,如果有人能建议我提供更好的解决方案,那就太好了。

代码:

获得人:

public static List getperson()
{
    Scanner keyboard = new Scanner(System.in);
    String line = null;
    int count = 0;

    List <Person> people = new ArrayList<>();

    while(!(line = keyboard.nextLine()).isEmpty()) {
      String[] values = line.split("\\s+");
      //System.out.print("entered: " + Arrays.toString(values) + "\n");
      int familyid = count++;
      for(String name :values)
      {
        Person person = new Person();
        person.setFamilyId(familyid);
        person.setName(name);
        person.setAllocated(false);

        people.add(person);
      }
    }
    return people;
}

映射:

public static List mapGifts(List pesonList) 
{
    Map<String , String> personMap = new HashMap<String , String>();

    Iterator<Person> itr = pesonList.iterator();
    Iterator<Person> itr2 = pesonList.iterator();
    List<String> sender =  new ArrayList<>();

    while(itr.hasNext())
        {
          Person p = itr.next();

              sender.add(p.getName()+"_"+p.getFamilyId());
              personMap.put(p.getName()+"_"+p.getFamilyId(), "");
             // p.setAllocated(true);

        }

          while(itr2.hasNext())
          {
              /*if(p.isAllocated())
              {*/

              // Separate Sender name and id from sender list
              //check this id match with new p1.getFamilyId()

              for(String sendername :sender)
              {
                 // System.out.println("Sender "+sendername);
                  personMap.put(sendername, "");

              String[] names = sendername.split("_");
              String part1 = names[0]; // 004
              String familyId = names[1]; // 004


              Person p2 = itr2.next();
              System.out.println(p2.getFamilyId() +"   "+familyId +" "+p2.isAllocated());

              if(p2.isAllocated())
              {
                  for ( String value: personMap.values()) {
                        if ( value != sendername) {

                        }
                    }

              }
              if( p2.getFamilyId() != Integer.parseInt(familyId))
              {

              // add values in map
              }
              }

              break;
            //  Person newPerson = personLists.get(j);

          }

    for (Iterator it = personMap.entrySet().iterator(); it.hasNext();) 
    {
          Map.Entry entry = (Map.Entry) it.next();
          Object key = entry.getKey();
          Object value = entry.getValue();

          System.out.println("Gifts "+key+"=>"+value);
        }
    return pesonList;
}

由于

1 个答案:

答案 0 :(得分:0)

从我读过的内容来看,你只关心与人匹配。它们如何匹配并不重要。也就是说,我假设您有一个FamilyID列表,以及每个人的名单,您可以根据家庭ID对人员列表进行排序。

我们打电话给他们:

List<FamilyID> families;和 分别为LinkedList<Person> people;。 (您可以将FamilyID设为枚举类)

我们需要两个哈希图。一个给出familyID的家庭成员的列表(基本上是邻接列表):

HashMap<FamilyID, List<Person>> familyMembers;

和一个生成发送者(密钥)和接收者(值)对的列表:

HashMap<Person, Person> pairs;

一个有用的功能可能是,当给出一个人及其家庭ID时,我们可以找到可以从他们那里接收的下一个可用的人。

String generateReceiver(Person newSender, FamilyID familyID);

这种方法的实现应该非常简单。您可以遍历人员列表并检查当前人员是否不是家庭成员。如果该条件通过,则将其从“人员”列表中删除,这样您就不会再次尝试迭代它们。如果您正在使用链接列表,则删除为O(1),因为您已经拥有该引用。在遍历的最坏情况列表是n + n - 1 + ... + 2次以获得O(n ^ 2)时间效率(即,您有一个大家庭和许多小家庭)。解决这个问题的方法是抛弃LinkedList,使用基于数组的列表,并保留一个单独的索引值数组,这些索引值对应于每个“当前可用的指定系列接收器”。当您将每个家庭的人员添加到人员列表时,您将初始化这些值(即,家庭1的开始是索引“0”;如果家庭1有2个人,则家庭2的开始将是索引“2”)。如果您每次添加发送器 - 接收器对时只增加当前可用的接收器索引,这将使函数O(1)成为时间。 (如果你想了解更多细节,请给我留言!)

最后但并非最不重要的是,循环正在为所有人这样做。

 for (List<Person> family : familyMembers)
  for (Person person : family)
   {
     // get the next available receiver who is not a family member
     // add the family member and its receiver to "pairs" hash
   }

请注意,上面的循环是伪代码。如果您想知道是否使用此方法生成冲突的接收器/发送器,则不会。人员列表基本上充当接收者列表。无论您采用people列表的哪种方式,generateReceiver(...)都会消除算法看到错误接收器的可能性。根据效率,如果您执行基于数组的实现,那么您将在O(N)时间生成所有对值,其中N是总人数。程序本身也是O(N)空间。

当然,这完全基于您有足够的人匹配发送者 - 接收者对的假设。你需要添加铃声和口哨来检查特殊情况。

希望这有帮助!祝你好运!