I'm looking for a Java built-in data structure that would be the best at handling adjacent rooms.
I have a grid/floor divided into randomly generated rooms like so:
+ + + + + + + + + + + + + + + + + + + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
and i'm looking for a data structure in which it would be fastest/easiest to store this grid and map out what rooms neighbour what rooms.
Does anyone have a suggestion?
thanks
You just need to store:
the opposite corners of each room
the adjacency graph/matrix of the graph formed by rooms as nodes and adjacency as the edge.
You can use a graph to represent rooms as nodes and neighboring relationship as edges.
You can represent graphs in many different ways. In this case, since the relationship is sparse, it's better to use adjacency list instead of adjacency matrix.
In Java, the graph can be represented with Map<Room,List<Room>>. Basically, it is what it says: it's a map from a Room to a list of its neighboring Rooms.
Alternatively, if you prefer to work with basic integers and arrays, you can use an adjacency matrix representation boolean[][] adj, where adj[i][j] == true if and only if room i and room j are neighbors.
Related
This question already has an answer here:
Add item to arraylist if it does not already exist in list
(1 answer)
Closed last year.
This post was edited and submitted for review last year and failed to reopen the post:
Original close reason(s) were not resolved
Below is the sample code
String jsonString = "{\n" +
" \"models\":[\n" +
" {\n" +
" \"model\":{\n" +
" \"code\":\"ALL\",\n" +
" \"type\":null,\n" +
" \"name\":\"ALL\",\n" +
" \"feature_types\":null\n" +
" }\n" +
" },\n" +
" {\n" +
" \"model\":{\n" +
" \"code\":\"102e\",\n" +
" \"defaultLookup\":\"false\",\n" +
" \"type\":\"SIT\",\n" +
" \"name\":\"MUSTANG\",\n" +
" \"feature_types\":[\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"A\",\n" +
" \"desc\":\"All feature types\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"B\",\n" +
" \"desc\":\"Series\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"C\",\n" +
" \"desc\":\"BodyStyle\"\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
" },\n" +
" {\n" +
" \"model\":{\n" +
" \"code\":\"980p\",\n" +
" \"defaultLookup\":\"false\",\n" +
" \"type\":\"SIT\",\n" +
" \"name\":\"Ranger\",\n" +
" \"feature_types\":[\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"C\",\n" +
" \"desc\":\"All feature types\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"D\",\n" +
" \"desc\":\"Series\"\n" +
" }\n" +
" } \n" +
" ]\n" +
" }\n" +
" },\n" +
" {\n" +
" \"model\":{\n" +
" \"code\":\"kkpou\",\n" +
" \"defaultLookup\":\"false\",\n" +
" \"type\":\"UAT\",\n" +
" \"name\":\"Transit Custom\",\n" +
" \"feature_types\":[\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"F\",\n" +
" \"desc\":\"All feature types\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"G\",\n" +
" \"desc\":\"Series\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"H\",\n" +
" \"desc\":\"Payload\"\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
" }\n" +
" ]\n" +
"}";
for(int i = 0; i<myData.size();i++)
{
String type = "SIT";
FeaturedItems item = resultList.stream().filter(featureItem -> type != null && type.equals(featureItem.getType())).findFirst().orElse(null);
if (type != null) {
item = FeaturedItems.builder().type(type).items(new ArrayList<>()).build();
resultList.add(item);//if the item already exists in the list don't add the new item, instead just add the elements in the exisiting item.
//tried the below commented code to add the item if it doesn't contain in the list -- start
/*boolean flagFound = false;
for (FeaturedItems featureItem : resultList) {
if (featureItem.getType().equalsIgnoreCase(type)) {
flagFound = true;
break;
}
}
if(!flagFound) resultList.add(item);*/
//tried the above commented code to add the item if it doesn't contain in the list -- End
for (int count = 0; count < features.size(); count++) {
String id = getFid(count);
MyDataBuild build = ....//logic to set values in the properties
item.getItems().add(build);
}
}
}
lookUpData.setFeatureGroups(resultList);
}
}
If the type value is already defined in the defined featureItems, then instead of creating the new object in the featureItems list, i need to add the unique items(desc,id) to the existing items element for the matching type. The code snippet mentioned above doesn't add the elements to the existing items if the type is matching in the featureItems list, instead it is creating the new element as shown in the output json sample.
Using a Map instead will make your live much easier. However your example is missing some data so it's a bit hard to understand what is actually happening in your code. So I can give you only a simple example for the usage.
Map<String, FeaturedItems> resultMap = new HashMap<>();
// Get the FeaturedItems for the given type. If none is present create a new one.
FeaturedItems items = resultMap.computeIfAbsent(type, k -> FeaturedItems.builder().type(k).items(new ArrayList<>()).build());
// Add your item to the list
Sale newItem // Obtain new item
items.getItems().add(newItem);
I created an app that uses Leaflet in it.
In the screen where the map is, there is also a progressBar where I allow uses to search in a specific radius.
The moment they change the value in the progressBar, it changes the size of the circle marker inside the map.
I had like that my map will change its zoom to fit that circle in it.
My code for loading the map is:
String Map_HTML = "<html>\n" +
"<head>\n" +
"\n" +
" <title>Quick Start - Leaflet</title>\n" +
"\n" +
" <meta charset=\"utf-8\" />\n" +
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n" +
"\n" +
" <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"docs/images/favicon.ico\" />\n" +
"\n" +
" <link rel=\"stylesheet\" href=\"https://unpkg.com/leaflet#1.4.0/dist/leaflet.css\" integrity=\"sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA==\" crossorigin=\"\"/>\n" +
" <script src=\"https://unpkg.com/leaflet#1.4.0/dist/leaflet.js\" integrity=\"sha512-QVftwZFqvtRNi0ZyCtsznlKSWOStnDORoefr1enyq5mVL4tmKB3S/EnC3rRJcxCPavG10IcrVGSmPh6Qw5lwrg==\" crossorigin=\"\"></script>\n" +
"\n" +
"\n" +
"\n" +
"<style>\n" +
"body {\n" +
"padding: 0;\n" +
"margin: 0;\n" +
"}\n" +
"html, body, #map {\n" +
"height: 100%;\n" +
"width: 100%;\n" +
"}\n" +
"</style>\n" +
"</head>\n" +
"<body>\n" +
"\n" +
"\n" +
"\n" +
"<div id=\"mapid\" style=\"width: " + dpWidth + "px; height: " + dpHeight * 0.3 + "px;\"></div>\n" +
"<script>\n" +
"\n" +
"var mymap = L.map('mapid',{zoomControl: false}).setView([" + Lat + ", " + Lon + "], 10);\n" +
"\n" +
" L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {\n" +
" minZoom: 7,\n" +
" maxZoom: 17,\n" +
" attribution: '© OpenStreetMap contributors' \n" +
" }).addTo(mymap);\n" +
"\n" +
"mymap.attributionControl.setPosition('topleft')\n" +
"L.control.zoom({\n" +
"position: 'bottomright'\n" +
"}).addTo(mymap);\n" +
"L.marker([" + Lat + ", " + Lon + "]).addTo(mymap)\n" +
" .bindPopup(\"<b>My Location</b>\").openPopup();\n" +
"\n" +
"L.circle([" + Lat + ", " + Lon + "], " + Radius + ", {\n" +
" color: 'red',\n" +
" fillColor: '#8275FE',\n" +
" fillOpacity: 0.4,\n" +
" weight: '0'\n" +
"}).addTo(mymap);\n" +
"\n" +
"\n" +
"var popup = L.popup();\n" +
"\n" +
"</script>\n" +
"\n" +
"</body>\n" +
"</html>";
where Radius is a parameter I insert based on the value of the progressBar.
Right now it always initializes the map with zoom: 10 because I don't know how to change it dynamically as I want.
Any way to do so?
Thank you
the map can fit to the bounds of the circle with mymap.fitBounds(circle.getBounds());.
Change your code to:
"var circle = L.circle([" + Lat + ", " + Lon + "], " + Radius + ", {\n" +
" color: 'red',\n" +
" fillColor: '#8275FE',\n" +
" fillOpacity: 0.4,\n" +
" weight: '0'\n" +
"}).addTo(mymap);\n" +
"mymap.fitBounds(circle.getBounds());\n" +
I have the following data, which is a list of lists:
"segmentation": [[239.97,260.24,222.04,270.49,199.84,253.41,213.5,227.79,259.62,200.46,274.13,202.17,277.55,210.71,249.37,253.41,237.41,264.51,242.54,261.95,228.87,271.34]]
What I need to do is to parse the information to a JSON object without removing the second braces.
I tried it with Jackson, but this fails with any data types.
Do you have any idea how to handle this?
Parse to JsonNode will work. I think u try with invalid json. check:
String value = "{\n" +
" \"segmentation\": [\n" +
" [\n" +
" 239.97,\n" +
" 260.24,\n" +
" 222.04,\n" +
" 270.49,\n" +
" 199.84,\n" +
" 253.41,\n" +
" 213.5,\n" +
" 227.79,\n" +
" 259.62,\n" +
" 200.46,\n" +
" 274.13,\n" +
" 202.17,\n" +
" 277.55,\n" +
" 210.71,\n" +
" 249.37,\n" +
" 253.41,\n" +
" 237.41,\n" +
" 264.51,\n" +
" 242.54,\n" +
" 261.95,\n" +
" 228.87,\n" +
" 271.34\n" +
" ]\n" +
" ]\n" +
"}";
JsonNode jsonNode = new ObjectMapper().readTree(value);
I have this array that shows the user the indexes of the position on a board of a game I'm making, the board is hexagonal and the notations bellow aren't finished yet because I'm to lazy to finish them right now :), but I'm wondering how can I print it on the console while keeping the format.
Thanks in advance
public static final String[] NOTATION = {
" 0/4 0/6 0/8 0/10 0/12 ",
" 1/3 1/5 1/7 1/9 1/11 1/13 ",
" 2/2 2/4 2/6 2/8 2/10 2/12 2/14 ",
" F + + + + + + + + ",
" E + + + + + + + + + ",
" D + + + + + + + + 9",
" C + + + + + + + 8 ",
" B + + + + + + 7 ",
" A + + + + + 6 ",
" 1 2 3 4 5 "
};
I recommend making a method you can call that prints it so you can print it easily many times, for example printBoard:
public static void printBoard() {
for (String str : NOTATION) {
System.out.println(str);
}
}
This utilizes an enhanced for loop to iterate through the array, and print each String moving to the next line with println.
Use it with:
public static void main(String[] args) {
printBoard();
}
Output:
0/4 0/6 0/8 0/10 0/12
1/3 1/5 1/7 1/9 1/11 1/13
2/2 2/4 2/6 2/8 2/10 2/12 2/14
F + + + + + + + +
E + + + + + + + + +
D + + + + + + + + 9
C + + + + + + + 8
B + + + + + + 7
A + + + + + 6
1 2 3 4 5
Note: I recommend reworking this into not using static and instead using OOP in something like a Board class.
My database has "diary" table and "food" table. In diary table I have following columns: date, food1,food2, ...food10. In food table I have: id, name, allergen1, allergen2, allergen3. So basically you log up to 10 foods a day to diary. Now I'm trying to build a query which would let me find last date that I've eaten food with allergen3. So that's the query I came up with, which you probably know is not working ;-)
Cursor findDateRes = db.rawQuery("SELECT date(" + DIARY_COL_DATE + ") FROM " + DIARY_TABLE
+ " INNER JOIN " + FOOD_TABLE + " food1 ON (food1." + FOOD_COL_1 + " = " + DIARY_TABLE + "." + DIARY_COL_F1 + ")"
+ " INNER JOIN " + FOOD_TABLE + " food2 ON (food2." + FOOD_COL_1 + " = " + DIARY_TABLE + "." + DIARY_COL_F2 + ")"
+ " INNER JOIN " + FOOD_TABLE + " food3 ON (food3." + FOOD_COL_1 + " = " + DIARY_TABLE + "." + DIARY_COL_F3 + ")"
+ " INNER JOIN " + FOOD_TABLE + " food4 ON (food4." + FOOD_COL_1 + " = " + DIARY_TABLE + "." + DIARY_COL_F4 + ")"
+ " INNER JOIN " + FOOD_TABLE + " food5 ON (food5." + FOOD_COL_1 + " = " + DIARY_TABLE + "." + DIARY_COL_F5 + ")"
+ " INNER JOIN " + FOOD_TABLE + " food6 ON (food6." + FOOD_COL_1 + " = " + DIARY_TABLE + "." + DIARY_COL_F6 + ")"
+ " INNER JOIN " + FOOD_TABLE + " food7 ON (food7." + FOOD_COL_1 + " = " + DIARY_TABLE + "." + DIARY_COL_F7 + ")"
+ " INNER JOIN " + FOOD_TABLE + " food8 ON (food8." + FOOD_COL_1 + " = " + DIARY_TABLE + "." + DIARY_COL_F8 + ")"
+ " INNER JOIN " + FOOD_TABLE + " food9 ON (food9." + FOOD_COL_1 + " = " + DIARY_TABLE + "." + DIARY_COL_F9 + ")"
+ " INNER JOIN " + FOOD_TABLE + " food10 ON (food10." + FOOD_COL_1 + " = " + DIARY_TABLE + "." + DIARY_COL_F10 +
") WHERE 1 NOT IN (food1." + FOOD_COL_5 +
",food2." + FOOD_COL_5 +
",food3." + FOOD_COL_5 +
",food4." + FOOD_COL_5 +
",food5." + FOOD_COL_5 +
",food6." + FOOD_COL_5 +
",food7." + FOOD_COL_5 +
",food8." + FOOD_COL_5 +
",food9." + FOOD_COL_5 +
",food10." + FOOD_COL_5 +
") ORDER BY date(" + DIARY_COL_DATE + ") ASC LIMIT 1", null);
"FOOD_COL_1" stands for id and "FOOD_COL_5" stands fro allergen3.
Thank you for looking. Any input will be appreciated.