所以我试图创建一个夹具列表generartor。为简单起见,该计划并未考虑家庭和远程设备。程序使用generateFixtures()方法每轮生成固定装置,然后重复指定的轮数,直到生成所有固定装置。
generateFixtures方法在其参数中传递一个arrayList,该分区中的所有团队都需要为该轮生成固定装置。传递的arrayList也总是包含20个团队。然后创建两个字符串,其中包含arraylist中内部的随机团队的值。然后,generateFixtures()使用alreadyUsed()方法检查其中一个团队是否已用于该轮次。它还会检查两支球队在整个赛季中是否已经固定(但我会在稍后详细解释这部分内容)。然后进行进一步检查以确保两个团队不同(在team1 == team2中)。当所有检查完成后,它将两个团队放入夹具列表图中,称为fixturesDone。并且还将两个团队放入“使用过的”中。 arraylist使得这两支队伍不再被用于那一轮。它不断重复while循环,直到所有团队都被固定(因为arraylist' used' size大于或等于19)。然后在main方法中设置一个循环,以保持循环generateFixtures()方法,直到整个赛季完成所有灯具。
问题出现在&fixtesDone' map或alreadyFixtured()方法。老实说,不确定哪一个可能导致问题。当我从if语句中直接从generateFixtures方法打印出灯具时,会生成灯具,但是经常会出现重复的灯具,而当我从“灯具”中打印出灯具时。地图没有重复的灯具,但似乎只有20个灯具存在,并且它总是20也表明我可能在其中一个循环中弄乱了一些东西。我现在已经解决了这个问题几个小时了,我真的很困惑,所以任何帮助都会非常感激:)
无论如何,在我看来,我在这里所说的是必要的代码,祝你好运。
public static void generateFixtures(ArrayList<String> al){
ArrayList<String> used = new ArrayList<String>();
while(used.size() <= 19){
String team = al.get(showRandomInteger(0, 19, r));
String team2 = al.get(showRandomInteger(0, 19, r));
if(alreadyUsed(used, team, team2) == false && alreadyFixtured(fixturesDone, team, team2) == false && !team.equals(team2)){
fixturesDone.put(team, team2);
used.add(team);
used.add(team2);
System.out.println(team + "vs. " + team2);
}
}
System.out.println("\n New week \n");
}
public static boolean alreadyFixtured(Map <String, String> m, String team1, String team2){
if(m.containsKey(team1) || m.containsKey(team2)){
for(Map.Entry<String, String> entry : m.entrySet()){
if((entry.getKey().equals(team1) && entry.getValue().equals(team2)) || (entry.getKey().equals(team2) && entry.getValue().equals(team1)) ){
return true;
}else{
return false;
}
}
}else{
return false;
}
return false;
}
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
for(int i = 0; i <= 19; i++){
generateFixtures(ReadXML(1));
}
System.out.println("\n Map version: ");
for(Map.Entry <String, String> entry : fixturesDone.entrySet()){
System.out.println(entry.getKey() + " vs. " + entry.getValue());
}
}
答案 0 :(得分:1)
你的alreadyFixtured
逻辑搞砸了。它只会检查地图中的第一个条目,因为只检查foreach循环中的第一个条目后返回true或false。真的可以用以下代码替换你的代码:
if(m.containsKey(team1))
return m[team1].equals(team2);
if(m.containsKey(team2))
return m[team2].equals(team1);
return false;
但是您还需要比此fixturesDone
地图更好的数据结构。这让我想到了下一点。
你的fixturesDone地图(我假设是全局的)几乎没用。您只能比较最多2个前几轮,因为每个键只能在地图中出现一次,并且您覆盖每次调用generateFixtures的一半键值对。您应该将假定的Map<String, String> fixturesDone
更改为Map<String, ArrayList<String>>
,在这种情况下,您需要将alreadyFixtured
逻辑更改为:
if(m.containsKey(team1))
return m[team1].contains(team2);
if(m.containsKey(team2))
return m[team2].contains(team1);
return false;
您还应该将团队选择更改为do-while循环:
String team, team2;
do{
team = al.get(showRandomInteger(0, 19, r));
}while(used.contains(team));
do{
team2 = al.get(showRandomInteger(0, 19, r));
}while(used.contains(team2) || team2.equals(team1));
然后可以将后续的if语句写成:
if(!alreadyFixtured(fixturesDone, team, team2))
但是,你仍然有一个潜在的问题,即在特定的一轮中只剩下已经相互比赛的球队,在这种情况下你的代码将无限循环。这并不像听起来那么微不足道。以某种循环方式生成所有灯具可能更容易,然后随机化这些灯具的发生顺序。