检查集合是否对称的有效方法

时间:2017-02-14 12:05:08

标签: java algorithm

我需要编写一个验证器来检查使用Gson从JSON解析的房间,对于每对房间A和B,如果你可以从A到B,那么你可以从B到A。 / p>

以下是JSON的格式: https://jsfiddle.net/tgtbqzky/

{
  "initialRoom": "MatthewsStreet",
  "rooms": [
    {
      "name": "MatthewsStreet",
      "description": "You are on Matthews, outside the Siebel Center",
      "directions": [
        {
          "direction": "East",
          "room": "SiebelEntry"
        }
      ]
    },
    {
      "name": "SiebelEntry",
      "description": "You are in the west entry of Siebel Center.  You can see the elevator, the ACM office, and hallways to the north and east.",
      "directions": [
        {
          "direction": "West",
          "room": "MatthewsStreet"
        },
        {
          "direction": "Northeast",
          "room": "AcmOffice"
        },
        {
          "direction": "North",
          "room": "SiebelNorthHallway"
        },
        {
          "direction": "East",
          "room": "SiebelEastHallway"
        }
      ]
    },
    {
      "name": "AcmOffice",
      "description": "You are in the ACM office.  There are lots of friendly ACM people.",
      "directions": [
        {
          "direction": "South",
          "room": "SiebelEntry"
        }
      ]
    },
    {
      "name": "SiebelNorthHallway",
      "description": "You are in the north hallway.  You can see Siebel 1112 and the door toward NCSA.",
      "directions": [
        {
          "direction": "South",
          "room": "SiebelEntry"
        }, 
        {
          "direction": "NorthEast",
          "room": "Siebel1112"
        }
      ]
    },
    {
      "name": "Siebel1112",
      "description": "You are in Siebel 1112.  There is space for two code reviews in this room.",
      "directions": [
        {
          "direction": "West",
          "room": "SiebelNorthHallway"
        }
      ]
    },
    {
      "name": "SiebelEastHallway",
      "description": "You are in the east hallway.  You can see Einstein Bros' Bagels and a stairway.",
      "directions": [
        {
          "direction": "West",
          "room": "SiebelEntry"
        },
        {
          "direction": "South",
          "room": "Siebel1314"
        },
        {
          "direction": "Down",
          "room": "SiebelBasement"
        }
      ]
    },
    {
      "name": "Siebel1314",
      "description": "You are in Siebel 1314.  There are happy CS 126 students doing a code review.",
      "directions": [
        {
          "direction": "North",
          "room": "SiebelEastHallway"
        }
      ]
    },
    {
      "name": "SiebelBasement",
      "description": "You are in the basement of Siebel.  You see tables with students working and door to computer labs.",
      "directions": [
        {
          "direction": "Up",
          "room": "SiebelEastHallway"
        }
      ]
    }
  ]
}

我想知道要走的路是两个嵌套for循环,其中外部for循环将遍历所有房间,内部将循环遍历每个循环内的每个方向,然后我会添加每对我进入一个ArrayList。

如果我遇到已经存在的东西,我会将它从ArrayList中删除,如果在我的for循环结束时,ArrayList仍然包含一个元素,这意味着它的相应对不存在,因此JSON无效。如果ArrayList的大小为零,则数据有效。

有没有人有更有效的方法来解决这个问题?我觉得因为它基本上证明了给定的集合是否是对称的,所以必须有更优化的方法。

3 个答案:

答案 0 :(得分:1)

您应该能够通过定义一对房间的“规范名称”来验证集合的对称性,例如,按字母顺序排列对中的房间名称,并将所有房间对映射到其规范名称:

NA

这将为一对房间生成相同的密钥> datetimes = c("Thu Dec 01 2016 14:53:38 GMT+0100 (CET)", "Thu Dec 01 2016 14:54:38 GMT+0100 (CET)", "Thu Dec 01 2016 14:55:38 GMT+0100 (CET)") > class(datetimes) [1] "character" > c_datetimes = strptime(datetimes, format = '%a %b %d %Y %H:%M:%S') > c_datetimes [1] NA NA NA ,其中一个房间为<input type="file" name="galleryImage" class="filestyle" data-buttonText="Select a Image">,另一个房间为static String canonicalName(String roomA, String roomB) { if (roomA.compareTo(roomB) < 0) { return roomA + "|" + roomB; } else { return roomB + "|" + roomA; } } ,无论订单如何。

现在您可以将它们映射到列表,如下所示:

"AcmOffice|MatthewsStreet"

在浏览完所有对之后,检查地图中的列表:

  • 如果列表有两个不同的项目,一切都很好
  • 如果列表中有一个项目,则缺少对称项目
  • 如果列表包含两个以上的项目,则有重复项

答案 1 :(得分:0)

  1. 为一对房间A,B,方向
  2. 构建代理对象
  3. 实施等于和比较
  4. 实施方法以获得对面的房间
  5. 将您反序列化的元素放在数组中。
  6. 使用地图检查是否找到了相反的方式。
  7. 它在O(n)

    中运行

    哪个给出了

    import java.util.*;
    import java.lang.*;
    import java.io.*;
    
    class RoomPath implements Comparable<RoomPath> 
    {
        String from;
        String to;
        String direction;
    
       public RoomPath(String A, String B, String dir)
       {
           from = A;
           to = B;
           direction = dir;
       }
    
       public RoomPath opposite()
       {
            String oppDirection ="";
            switch(direction)
            { 
                case "North" : oppDirection = "South"; break;
                case "South" : oppDirection = "North"; break;
                case "West" : oppDirection = "East"; break;
                case "East" : oppDirection = "West"; break;
            }
            return new RoomPath(to, from, oppDirection);
       }
    
       public int compareTo(RoomPath other)
       {
            int v1 = from.compareTo(other.from);
            if(v1 == 0)
            {
                v1 = to.compareTo(other.to);
                if(v1 == 0)
                {
                    return direction.compareTo(other.direction);
                }
                return v1;
            }
            return v1;
       }
    
       public bool equals(Object e)
       {
           if (!(e instanceof RoomPath)) return false;
           RoomPath path = (RoomPath )e;
           return compareTo(e) == 0;
       }
    
        public int hashCode() {
            int dirnumber = 0;
            switch(dirnumber)
            { 
                case "North" : dirnumber = 0; break;
                case "South" : dirnumber = 1; break;
                case "West" : dirnumber = 2; break;
                case "East" : dirnumber = 3; break;
            }
    
            return (from.hashCode() + 31 * b.hashCode() ) << 2 | dirnumber;
            //left as exercise
            return 0;
        }
    
    
    }
    
    
    /* Name of the class has to be "Main" only if the class is public. */
    class Ideone
    {
        public static void main (String[] args) throws java.lang.Exception
        {
            List<RoomPath > roompaths = ... ; //the parsing function
            List<RoomPath > symetrics = new ArrayList<RoomPath>();
            Map<RoomPath, bool> syms = new HashMap<>();
            for (RoomPath path : roompaths) 
            {
                if(!syms.containsKey(path))
                {
                     syms.put(path, false);
                }
    
                if(syms.containsKey(path.opposite()))
                {
                    symetrics.insert(path);
                }
            }
            bool allok = symetrics.size()*2 = roompaths.size();
        }
    }
    

答案 2 :(得分:0)

我更愿意将JSON转换为像这样的二维矩阵:

enter image description here

其中:West为W,Est为E,Nord为N,S为Sud,X表示缺少路​​径

就像那样,知道你是否可以从一个房间到另一个房间很简单。你只需要实现一些简单的循环来迭代矩阵。