Increment individual values in array Java - java

I want to know how to increment certain indexes in an array.
int indexArrayHIS[] = new int[15];
int indexArrayFIX[] = new int[20];
indexArrayHIS[] is an array consisting out of index values:
6 9 9 17 0 19 16 1 0 7 1 18 16 8 10
I want fill indexArrayFIX[] with the number of each index instance. For example, there are 2 "9s" so at index 9 of indexArrayFIX[] I want to display a 2:
indexArrayFIX[] should output:
2 2 0 0 0 0 1 1 1 2 1 0 0 0 0 0 2 1 1 1 0
Hope this makes sense
Thanks

Why not just?
for (int i = 0; i < indexArrayHIS.length; i++) {
indexArrayFIX[indexArrayHIS[i]]++;
}

Related

What is wrong with my Floyd Warshall algorithm?

Here is the problem link
Approach:
My approach is to simply give every other node the chance to be an in-between node for every 2 pairs of vertices i and j.
Below is my code for Floyd Warshall algorithm:
class Solution{
public void shortest_distance(int[][] mat){
int N = mat.length;
for(int i = 0; i < N; ++i){
for(int j = 0; j < N; ++ j){
for(int k = 0; k < N; ++k){
if(mat[i][k] != -1 && mat[k][j] != -1 && (mat[i][j] == -1 || mat[i][j] > mat[i][k] + mat[k][j])){
mat[i][j] = mat[i][k] + mat[k][j];
}
}
}
}
}
}
This gives wrong answer for the below case:
Input
12
0 4 2 1 2 9 4 8 -1 4 -1 -1
9 0 3 6 2 6 2 3 6 -1 -1 3
7 1 0 10 8 9 1 3 -1 7 -1 10
5 1 9 0 3 -1 1 10 7 1 -1 7
-1 5 1 4 0 2 10 4 10 6 4 5
7 8 3 7 5 0 5 1 3 5 7 2
6 -1 6 1 10 7 0 10 -1 -1 7 7
-1 3 2 7 4 -1 4 0 10 5 6 10
10 6 1 10 4 4 7 10 0 4 7 4
1 1 6 8 8 9 2 10 6 0 -1 3
5 9 3 -1 4 3 -1 -1 -1 3 0 1
2 2 8 6 2 4 4 3 -1 3 4 0
My output
0 2 2 1 2 4 2 5 7 2 6 5
5 0 3 3 2 4 2 3 6 4 6 3
6 1 0 2 3 5 1 3 7 3 7 4
2 1 4 0 3 5 1 4 7 1 7 4
6 2 1 3 0 2 2 3 5 4 4 4
4 4 3 5 4 0 4 1 3 5 6 2
3 2 5 1 4 6 0 5 8 2 7 5
6 3 2 4 4 6 3 0 9 5 6 6
5 2 1 3 4 4 2 4 0 4 7 4
1 1 3 2 3 5 2 4 6 0 7 3
3 3 3 4 3 3 4 4 6 3 0 1
2 2 3 3 2 4 4 3 7 3 4 0
Expected Output
0 2 2 1 2 4 2 5 7 2 6 5
5 0 3 3 2 4 2 3 6 4 6 3
4 1 0 2 3 5 1 3 7 3 7 4
2 1 4 0 3 5 1 4 7 1 7 4
5 2 1 3 0 2 2 3 5 4 4 4
4 4 3 5 4 0 4 1 3 5 6 2
3 2 5 1 4 6 0 5 8 2 7 5
6 3 2 4 4 6 3 0 9 5 6 6
5 2 1 3 4 4 2 4 0 4 7 4
1 1 3 2 3 5 2 4 6 0 7 3
3 3 3 4 3 3 4 4 6 3 0 1
2 2 3 3 2 4 4 3 7 3 4 0
Note: I have also observed that if I move the k loop out and make it the first loop, it works just fine. I am confused as to what is wrong with my current code.
It is all about states. This is more conceptual than any algorithmic implementation issue here.
As in your code,
for(i...)
for(j..)
for(k...)
mat[i][j] = mat[i][k] + mat[k][j];
The above states, for every pair of nodes i and j, check if any shortest path exists via every possible k. However, you are implicitly assuming that mat[i][k] and mat[k][j] are in already optimized states. This is incorrect as there is no real effort made in the code to bring them to that state.
Instead, you need to check for every pair of nodes i and j via only 1 value of k at a time. This is how you would be building the optimized states for every possible k one by one and the next one depending on the previous one. Hence, the below is correct version for this:
class Solution{
public void shortest_distance(int[][] mat){
int N = mat.length;
for(int k = 0; k < N; ++k){
for(int i = 0; i < N; ++i){
for(int j = 0; j < N; ++j){
if(mat[i][k] != -1 && mat[k][j] != -1 && (mat[i][j] == -1 || mat[i][j] > mat[i][k] + mat[k][j])){
mat[i][j] = mat[i][k] + mat[k][j];
}
}
}
}
}
}
Quoting from the Wiki.
The Floyd–Warshall algorithm compares all possible paths through the
graph between each pair of vertices. It is able to do this with
{\displaystyle \Theta (|V|^{3})}\Theta (|V|^{3}) comparisons in a
graph, even though there may be up to {\displaystyle \Omega
(|V|^{2})}{\displaystyle \Omega (|V|^{2})} edges in the graph, and
every combination of edges is tested. It does so by incrementally
improving an estimate on the shortest path between two vertices, until
the estimate is optimal.
Miscellaneous:
Although trivial, but I still think it is worth mentioning that the order of nodes used in the optimization process really doesn't matter. We simply need to shorten the distance(if exists and possible) node by node where every node is an intermediate candidate.
class Solution{
public void shortest_distance(int[][] mat){
int N = mat.length;
List<Integer> nodes = new ArrayList<>();
for(int i = 0; i < N; ++i) nodes.add(i);
Collections.shuffle(nodes);
for(int l = 0; l < nodes.size(); ++l){
int k = nodes.get(l);
for(int i = 0; i < N; ++i){
for(int j = 0; j < N; ++j){
if(mat[i][k] != -1 && mat[k][j] != -1 && (mat[i][j] == -1 || mat[i][j] > mat[i][k] + mat[k][j])){
mat[i][j] = mat[i][k] + mat[k][j];
}
}
}
}
}
}

Java DFS for adjacency matrix

I am working on a project to implement a DFS for a given adjacency matrix. I have the file reading in correctly and I have the program outputting a list of first encountered vertices, however, I am not getting the correct list. I am getting 1 2 6 5 7 3 4 8 but I need to get 1 2 6 7 4 3 5 8. I am not sure where I am going wrong, but any suggestions would help. Below I have attached the part of code the outputs the encountered vertices and the file with the adjacency matrix.
Code with the output:
public static void dfs(int vertex, boolean[] visitArray, ArrayList<Integer> DFSvertexList, ArrayList<Integer> DFSdeadEndList, int[][] DFStreeEdgeGraph, ArrayList<Integer> vertexList, ArrayList<Integer> iList, boolean[] visitArray2){
int ver = 0;
DFSvertexList.add(vertex);
visitArray[vertex] = true;
for(int i = 0; i <= dim-1; i++){
if(graph[vertex][i] == 1){
if(!visitArray[i]){
ver = i;
DFStreeEdgeGraph[vertex][i] = 1;
dfs(i, visitArray, DFSvertexList, DFSdeadEndList, DFStreeEdgeGraph, vertexList, iList, visitArray2);
DFSdeadEndList.add(i);
}
else if(i >= vertex && i != ver){
vertexList.add(vertex+1);
iList.add(i+1);
}
}
}
}
Here is the adjacency matrix:
0 1 0 0 1 1 0 0
1 0 0 0 0 1 1 0
0 0 0 1 0 0 1 0
0 0 1 0 0 0 0 1
1 0 0 0 0 1 0 0
1 1 0 0 1 0 0 0
0 1 1 0 0 0 0 1
0 0 0 1 0 0 1 0
Please let me know if more code is needed.

Reading a file with integers that may or may be delineated by spaces

So I have this file that is filled only with integers. I would like to, if possible, be able to read a file that may or may not have spaces delineating each integer.
Here are two visual examples.
The first one are integers that are not delineated by spaces while the second one are.
First Example:
020030090
000907000
900208005
004806500
607000208
003102900
800605007
000309000
030020050
Second Example:
0 3 8 0 12 0 15 16 6 0 4 0 0 0 0 0
0 11 5 0 1 0 0 14 13 0 3 9 12 7 0 0
0 0 0 0 6 0 0 0 0 12 0 14 0 0 0 16
10 16 0 6 2 13 0 0 0 8 7 0 0 0 0 0
3 10 1 0 13 0 0 15 0 9 0 16 5 0 0 0
0 0 16 0 0 0 0 11 14 0 13 12 0 3 0 0
4 0 7 8 0 0 12 9 0 0 0 0 0 0 11 0
0 6 0 0 16 0 0 0 11 5 0 0 15 0 0 2
11 0 0 12 0 0 8 2 0 0 0 1 0 0 14 0
0 7 0 0 0 0 0 0 3 11 0 0 8 16 0 9
0 0 13 0 3 6 0 7 16 0 0 0 0 11 0 0
0 0 0 2 5 0 14 0 15 0 0 4 0 13 7 1
0 0 0 0 0 14 5 0 0 0 16 2 13 0 8 10
14 0 0 0 8 0 9 0 0 0 0 11 0 0 0 0
0 0 6 15 7 1 0 3 12 0 0 13 0 2 5 0
0 0 0 0 0 15 0 12 1 14 0 3 0 6 16 0
Note:
I would also like to add that the second file might not be delineated by the same amount. This means that one integer could have one space after it and another integer could have 10 spaces after it.
What I have tried:
I have tried using the split("\s+") in combination with the replaceAll("", " ") but this not work in the second example because it would have more spaces and thus the split function would not work.
I have tried using replaceAll(" ", "") like this so that they have no spaces at all. Then I converted the string into a char array but that presented problems with integers greater than one digit(would not work with the second example as well).
Code:
public void initializeGrid(int grid[][], String fileName) throws FileNotFoundException, IOException
{
Scanner read = new Scanner(Paths.get(fileName));
int value;
for (int i = 0; i < ROWS; i++)
{
String line = read.nextLine();
String [] numbers = line.trim().split("\\s+");
for (int j = 0; j < COLUMNS; j++)
{
value = Integer.parseInt(numbers[j]);
grid[i][j] = value;
}
}
}
Following the recommendation of #dnault in the comments above, here's an implementation that uses the Java Collection framework instead of a 2d int array. This approach has an advantage over a 2d array in that the List for each row contains exactly as many entries as needed. Using arrays, if a line has less than COLUMN values, the array will contain zeros for all remaining values.
public List<List<Integer>> readFile(String fileName)
throws FileNotFoundException, IOException {
BufferedReader br = Files.newBufferedReader(Paths.get(fileName));
List<List<Integer>> values = new ArrayList<>();
for(String line; (line = br.readLine()) != null;){
String[] splitLine = line.trim().split("\\s+");
if(splitLine.length < 2)
values.add(parseSingleDigitValues(splitLine[0].toCharArray()));
else
values.add(parseDelimitedValues(splitLine));
}
return values;
}
private List<Integer> parseSingleDigitValues(char[] line) {
List<Integer> values = new ArrayList<>();
for(char c: line){
values.add(Integer.parseInt(String.valueOf(c)));
}
return values;
}
private List<Integer> parseDelimitedValues(String[] line) {
List<Integer> values = new ArrayList<>();
for(String str :line)
values.add(Integer.parseInt(str));
return values;
}
The resulting List<List<Integer>> can then be easily converted into a 2D int array using the following method:
private int[][] asArray(List<List<Integer>> lists){
int s1 = lists.size();
int s2 = 0;
for(List<Integer> sublist : lists){
if(sublist.size() > s2)
s2 = sublist.size();
}
int[][] arr = new int[s1][s2];
for(int i = 0; i < lists.size(); i++){
List<Integer> sublist = lists.get(i);
for(int j = 0; j < sublist.size(); j++){
arr[i][j] = sublist.get(j);
}
}
return arr;
}
EDIT In the end, if you clearly document your code/api then the burden is on the user to put it into proper use. I recommend you opt for simplicity in your API: Tell the user they must provide a space-delimited file. You can then provide a utility class that will convert a non-delimited file into a space-delimited file.

Rotate an object for placement in a 2d array

I'm trying to create a basic RTS style grid. The grid works perfectly and I can place object by setting a number to anything other than 0.
That's the easy part. currently im trying to allow each object that is placed to be rotated. The objects that can be rotated can be any size e.g. 1x1, 2x1, 3x4 etc, and all object have an entry block which needs to be rotated with the object.
For example.
My grid is empty
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
and I can place an object shown below:
1 2 1
1 1 1
which will place like
0 0 0 0 0 0 0
0 1 2 1 0 0 0 1 2 1
0 1 1 1 0 0 0 1 1 1
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
but when rotated it should place like
1 2 1 0 1 1 0 1 2 1 1 1
1 1 1 0 1 2 0 1 1 1 1 2
0 0 0 0 1 1 0 1 1
0 1 1 0 0 0 0 1 1
0 2 1 0 1 1 1 2 1 1 1 1
0 1 1 0 1 2 1 1 1 1 2 1
Im trying to figure out how this could be acheived in code considering that the object can be of different shapes? :(
1 1 2 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 2 1 1
1 1 1 1 1 1 2 1 2 1 1 1 1 1
1 1 1 1 1 1
I figured out how to accomplish this from another board on here.
First thing I did was store the object in a 2 dimensional array e.g.
1 2 1 1
1 1 1 1
I then transposed the array leaving me with this array
1 1
2 1
1 1
1 1
And then I rotated each row leaving me with my final rotated object
1 1
1 2
1 1
1 1
And for 180+ rotations I just use this technique again to reach the desired rotation :)
My final Array Class in Unity3D C#
using UnityEngine;
using System.Collections;
namespace Arrays {
public class Array {
public static int[,] Rotate(int[,] array)
{
return Rotate90 (array);
}
public static int[,] Rotate90(int[,] array)
{
return RotateArrayRow( Transpose(array) );
}
public static int[,] Rotate180(int[,] array)
{
return Rotate90(Rotate90(array));;
}
public static int[,] Rotate270(int[,] array)
{
return Rotate90(Rotate180(array));;
}
private static int[,] RotateArrayRow(int[,] array){
int x = array.GetLength(1);
int y = array.GetLength(0);
int[,] temp = new int[y,x];
for(int i=0; i<y; i++)
{
for(int j=0; j<x; j++)
{
temp[i,x-j-1] = array[i,j];
}
}
return temp;
}
public static int[,] Transpose(int[,] array){
int x = array.GetLength(1);
int y = array.GetLength(0);
int[,] temp = new int[x,y];
for(int i=0; i<y;i++){
for(int j=0; j<x; j++){
temp[j,i] = array[i,j];
}
}
return temp;
}
public static void Log(int[,] array){
for(int i=0; i<array.GetLength(0); i++)
{
string line = "";
for(int j=0; j<array.GetLength(1); j++)
{
line += array[i,j] + " ";
}
Debug.Log(line);
}
}
}
}
One thing to think about first is that to rotate your objects you only need to implement one rotation function: 90 degrees in one direction. The other rotations just repeat this operation 2 or 3 times, simplifying your logic.
There are two mappings from original to rotated array you need to consider:
How do the dimensions map?
How do the indices map?
1 is easy: the dimensions are swapped. A rotated 1x4 becomes 4x1.
2 depends on your implementation, but if you're using 2d coordinates [x, y] => [y, -x] or [-y, x] depending on direction of rotation.

How To Check For Diagonal Neighbors in a 2D Array and Set Current Value Equal to Number of Neighbors

I am trying to walk through a 2D array and count all diagonal neighbors that equal 0, then set the current position equal to the number of neighbors. For example:
0 5 0 9
0 5 0 3
1 9 4 6
7 0 0 9
Should change to
0 2 0 1
0 3 1 2
1 3 1 2
0 1 1 1
I am using the following code (I catch exceptions because there will be index out of bounds exceptions for all parameter numbers) :
int row, col, count;
count = 0;
// Standard for-loop used in walking through a 2D array
for (row = 0; row < NUM; row++) {
for (col = 0; col < NUM; col++) {
// Check top left neighbor
try {
if (grid[row - 1][col - 1] == 0) {
count++;
}
} catch (IndexOutOfBoundsException e) {
} // Check bottom left neighbor
try {
if (grid[row - 1][col + 1] == 0) {
count++;
}
} catch (IndexOutOfBoundsException e) {
} // Check top right neighbor
try {
if (grid[row + 1][col - 1] == 0) {
count++;
}
} catch (IndexOutOfBoundsException e) {
} // Check bottom right neighbor
try {
if (grid[row + 1][col + 1] == 0) {
count++;
}
} catch (IndexOutOfBoundsException e) {
} // Set current place in the array equal to number of 0 neighbors
grid[row][col]=count;
count = 0;
}
}
The issue is that my output is wrong. Instead of the supposed code, it changes to the following:
0 2 0 1
0 3 1 2
1 2 1 1
0 0 0 0
So the first two lines work , then the 3rd line has several OBO errors. Not sure what's even wrong with the last line, and I'm not sure where this is going wrong.
Summary
Original is:
0 5 0 9
0 5 0 3
1 9 4 6
7 0 0 9
That should change to:
0 2 0 1
0 3 1 2
1 3 1 2
0 1 1 1
But I'm getting:
0 2 0 1
0 3 1 2
1 2 1 1
0 0 0 0
Another Example Would Be:
Original:
5 0 0 3 9 5
0 0 9 5 3 0
0 0 0 9 7 3
7 0 5 0 9 5
0 0 3 0 0 0
9 5 0 3 7 0
Updated:
1 1 1 0 1 0
1 2 2 1 2 0
1 0 2 0 2 0
2 1 4 1 4 1
0 1 0 1 1 0
0 2 0 1 1 0
Any suggestions would be very much appreciated.
You start with
0 5 0 9
0 5 0 3
1 9 4 6
7 0 0 9
You start traversing from the top left and simultaneously modifying the matrix.
So after 2 rows have been modified, the intermediate matrix is
0 2 0 1
0 3 1 2
1 9 4 6
7 0 0 9
Now take into consideration the element at index [2][1]. In the original matrix, it had 3 zero neighbors, but this matrix only has 2, hence the difference in expected and obtained output.
Make a separate matrix to store the modified values.

Categories