所以我试图创建一个夹具列表生成器。为了简单起见,该程序没有考虑主场和客场夹具。该程序使用GenerateFixture()方法每轮生成夹具,然后重复指定数量的回合,直到生成所有夹具。
这个问题发生在“fix turesDone”映射或alreadyFix的()方法中。老实说,不确定是哪一个导致了这个问题。当我从if语句中直接从GenerateFixture方法打印出夹具时,会生成夹具,但经常会有重复的夹具,而当我从“fix turesDone”映射打印出夹具时,没有重复的夹具,但似乎只有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());
}
}
您的已经修复
逻辑一团糟。它只会检查地图中的第一个条目,因为您在检查foreach循环中的第一个条目后才返回true或false。真的,你可以用以下代码替换你的代码:
if(m.containsKey(team1))
return m[team1].equals(team2);
if(m.containsKey(team2))
return m[team2].equals(team1);
return false;
但是您还需要比这个fix turesDone
映射更好的数据结构。这将我引向我的下一点。
你的fix turesDone映射(我假设是全局的)几乎没有用。你最多只能与前两轮进行比较,因为每个键在映射中只能出现一次,并且每次调用GenerateFixture都会覆盖一半的键值对。你应该改变你假定的Map
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))
然而,你仍然有一个潜在的问题,在特定的回合中,只有已经互相比赛过的队伍,在这种情况下,你的代码会无限期地循环。这并不像听起来那么简单。以一种循环的方式生成所有的夹具,然后随机化这些夹具发生的顺序可能更容易。