Java 2D Array: Go through groups of entries and sum their values - java

Let's say that there exists a 2D Java array (4x6 for representation purposes) filled with numbers ranging from 1 to 9 in a random order.
What if one wanted to calculate the individual sum of all groups of numbers in that array?
Simple illustration:
In this particular case:
Sum of the blue area
Sum of the violet area
Sum of the red area
Sum of the yellow area
...
The following code works for any array, but only if each entry is precisely 1x1 big which is useless in this case (and any other case), as it simply goes through all entries.
for (int a = 0; a < x; a++) {
for (int b = 0; b < y; b++) {
sum = array[a][b];
}
}
How would you make it go through groups of entries and then sum all values located in an individual group?

startx, starty, endx, endy is the answer to that. You will iterate from start to end. This does require you to know (or be able to calculate) those variables. If not please clarify the exact structure.
If your array is declared like:
int[][] matrix = new int [4][6];
A rough example:
public int sumOfSubMatrix (int startx, int starty, int endx, int endy) {
int sum = 0;
for (int x = startx; x <= endx; x++) {
for (int y = starty; y <= endy; y++) {
sum += matrix[x][y];
}
}
return sum;
}
You simply add every "cell" to the sum variable.
Now, this is not possible if the "colors" were spread out, even one cell being off, then the algorithm has to something of them, like their position. If the structure is 100% chaotic then your best option is brute force with if-guards.

Related

Calculating largest euclidean distance between two values in a 2d array

I am trying to calculate the euclidean distance between 2 values in a 2d array. I need the largest, so I have 2 for loops to travers the arrays, and I also have a maxDistance variable to store the greatest distance as I compare.
My code looks like this
//Returns the largest Euclidean distance between any two cities
within the cities array
public static double furthestDistance(int[][] x)
{
int power;
double sum = 0.0;
int distance = 0;
int maxDistance = 0;
for (int i = 0; i < x.length; i++)
{
for(int j = 0; j<x[0].length; j++)
{
sum = (x[i][j] - x[i][i+1]) + (x[i][j] - x[i][j+1]);
power = (int) Math.pow(sum, 2);
distance = (int)Math.sqrt(power);
if (distance > maxDistance)
{
maxDistance = distance;
}
}
}
return Math.sqrt(sum);
}
I am having issues, getting an error that says my arrayIndex is out of bounds, but I am not sure what the ebst way to travers my array to find the largest distance between any two values in my 2d array of around 10 "x,y coordinates"
x is an array of cities which looks like this
int[][] cities0 = {{22,-45},{-20,-43},{-45,29},{41,35},{21,4},
{23,-37},{16,-19},{-44,-10},{26,15},{6,-30},{2,35},{6,-19}};
I am not sure if I am approaching the problem the right way of if I am even calculating the distance properly?
The Euclidean distance is
public static double calculateDistance(int[] array1, int[] array2)
{
double Sum = 0.0;
for(int i=0;i<array1.length;i++) {
Sum = Sum + Math.pow((array1[i]-array2[i]),2.0);
}
return Math.sqrt(Sum);
}
Now, the thing is that you have an array of points, each point is represented by a two-element array. The index out of bounds error stems from the fact that you have the line of
sum = (x[i][j] - x[i][i+1]) + (x[i][j] - x[i][j+1]);
which assumes that there is a next i and a next j, also, it assumes that the i'th element of x has at least i + 2 elements, which, if i > 0 will crash. Using the method I described at the start of my answer, your solution would look like:
double maxDistance = -1;
int firstPoint = -1;
int secondPoint = -1;
//notice that the limit is x.length - 1, because we will compare the penultimate
//item with the last
for (int i = 0; i < x.length - 1; i++) {
for (int j = i + 1; j < x.length; j ++) {
double d = calculateDistance(x[i], x[j]);
if (d > maxDistance) {
maxDistance = d;
firstPoint = i;
secondPoint = j;
}
}
}
Your Euclidean distance calculation was wrong in the initial code.
Also, the statement x[i][i+1] is problematic because you have tuples as data points and each tuple is in a different row, which means that the
elements in the array can be accessible by either x[i][0]or x[i][1] and any value greater than 1 in the second bracket will cause an IndexOutOfBounds Error.
Modifying the inner loop of the code can help you :
for(int j = i + 1; j<x.length; j++)
{
sum = Math.pow((x[i][0] - x[j][0]), 2) + Math.pow((x[i][1] - x[j][1]), 2);
distance = Math.sqrt(sum);
System.out.println(distance);
if (distance > maxDistance)
{
maxDistance = distance;
}
}
Since we have tuples as our coordinates, x[i][0] - x[j][0] denotes the difference between x-coordinates of the two points and x[i][1] - x[j][1] denotes the difference between y-coordinates. Using that notation, we calculate Euclidean distance. The rest is what you have wrote previously. Also change the variables to double rather than int for more precision in your calculations!
Note: This example is hard-coded for the input you gave in your question, you might need to modify it for using with different arrays.

How to check which points are in a circle?

Okay so say there is a grid, which I have stored as a 2 dimensional array, that is 10 by 10.
int[][] grid = new int[10][10];
The origin of the grid is at the bottom left, like a normal x y plane, and there is a circle of radius 5 in the centre of the grid at (5,5), like so:
I want to go through this array and basically check which points are inside the circle, but I do not want to loop through the entire array. By default, every point on a corner is not going to be in the circle, so I would want to ignore those, and similarly the points that are close to the corner, etc.
Just the points that are in the circle. I have a much bigger grid and looping through unnecessary stuff that I already know isn't in the circle would waste time. Is there a way to do this? Because, given that I already know the radius and centre of the circle, there should be a nice easy way to go through those points which are in the circle and change them from 0 to -1, for example.
Otherwise, I would stand to lose 100 - 25π ≈ 21.46% time.
BETTER CLARITY: I already know that I can bound the circle with a square, and loop through the points in that square and check each points distance from the centre of the circle (x^2 + y^2 < r^2), but this is what I am trying to avoid, due to the constant overhead every time of checking the bits that aren't in the circle, when I know they are not in the circle beforehand.
Ok, after a long discussion, here is the solution. You scan across one axis of a quarter slice, compute the extension to which you need to fill that quarter outwards and then fill all 4 quarters at once.
int n = 1000;
// you will need to think yourself about the odd number or elements
int r = n / 2;
int r2 = r * r;
Putting (0,0) at the centre of the matrix in both cases, the optimized solutions can look like this:
int[][] grid0 = new int[n][n];
for (int i = 0; i < r; i++) {
double m = Math.sqrt(r2 - i * i);
for (int j = 0; j < m; j++) {
grid0[r + i][r + j] = 1;
grid0[r + i][r - j] = 1;
grid0[r - i][r + j] = 1;
grid0[r - i][r - j] = 1;
}
}
As commented elsewhere, the extension of filling the circle is computed in O(n).
Here is the straightforward validation:
int[][] grid1 = new int[n][n];
// you will need to think yourself about the even number
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if ((i - r) * (i - r) + (j - r) * (j - r) < r2) {
grid1[i][j] = 1;
}
}
}
Both produce the same number of filled points.
Time measurements over 10000 executions (with array initialization outside of the time loop):
the optimized one 6.0s
the exhaustive one 15.6s
So, I do admit there is a difference, an astonishing one. Although for a fair comparison, the latter snippet should also be using a quarter slice of the circle.
One can speed up the optimized solution even further using some sort of memory copy routine to fill the values from 0 to the computed point rather than a plain loop, but that is beyond the scope.

Java - Two-Dimensional Arrays - Plotting Points

I have an assignment for a JAVA class I am taking. We are discussing two-dimensional arrays, however on this particular assignment, I can not figure out how to return back specific points and set those points with a specific value. Here is the assignment:
Write a method called create2DArray that will fill, create, and return
a 10 x 10 2d array with random numbers in the range of 1 to 100. Write
a method called print2DArray that will print a 10 x 10 2D array in row
column fashion. Write a method called createCoords that will search
the 2D array looking for any value that is evenly divisible by 3.
Once you have found a number you should log the row, column location.
This means when your method finishes it should produce a list of
coordinates that I can use to plot my graph. This method must also
return the number of coordinates that are divisible by 3 so that I
know how many points there are to plot. I am not particular as to how
the coordinates are returned back as long as I get a list of the row,
column locations. So, I will leave it to you to work out a mechanism
for returning the values. To test that you have logged the
coordinates create another function called fillLocations that will
fill the locations in the array you have logged with
-1. So, your program should flow in this order
create2DArray
print2DArray
createCoords
fillLocations
print2DArray
I understand and have completed create2DArray and print2DArray, but I can not figure out createCoords and fillLocations. Here is what I have so far, but it does not work and there are errors present:
public int createCoords(int row1, int col1){
int[][] coords = new int[row1][col1];
int[][] count = new int[0][0];
int co = 0;
for(int row = 0; row < 10; row++)
{
for(int col = 0; col < 10; col++)
{
if(coords[row][col] % 3 == 0)
co++;
return count[row][col];
}
}
return co;}
public int fillLocations(int[][] count){
int x = 0;
int y = 0;
for(int row = 0; row < 10; row++)
{
for(int col = 0; col < 10; col++)
{
if(count[row][col] % 3 == 0)
x = row;
y = col;
break;
}
}
return (x, y);}
As a programmer you'll nearly always need to research for doing different things. This research will be easier when you divide your problem to smaller problems.
For example you need to generate random numbers? So search on google that and you'll find this: How do I generate random integers within a specific range in Java?.
You need to create and return a 2D array? Google and see Syntax for creating a two-dimensional array
And with your art, put the pieces of the puzzle together in a way that gives your desired result.
public int[][] create2DArray() {
int[][] newArray = new int[10][10];
Random random = new Random();
int range = 100;
for(int i = 0; i < 10; i++)
{
for(int j = 0;j<arr[0].length;j++)
{
newArray[i][j]= (random.nextInt(range) + 1);
}
}
return newArray;
}
This method, creates and returns a 10*10 2D array filled with random generated numbers between 1-100. I'm sure you can write the rest of your program and enjoy from it by yourself.

Coordinate generation for memory card game

How can I generate (x, y) coordinates for a memory card game? Let's say I can set the number of cards, rows and columns. How would my for loop look like?
My general idea is as follows:
final int ROWS = 4;
final int COLUMNS = 5;
for(int i = 0; i<ROWS; i++){
for(int j = 0; j<COLUMNS; j++){
//calculate X coordinate
int index = some_calculation
MemoryCard memoryCard = new MemoryCard(x, y, index);
}
//calculate y coordinate
}
However, I'm having an issue creating my objects here. The above loop will go 4 times for i and 5 times for j. So, in total I have 20 objects there. But how do I get to my object's index?
Let's say I have an array list of my objects:
private ArrayList<MemoryCard> objects = new ArrayList<MemoryCard>();
//parameters for MemoryCard object are (float x, float y, Texture frontImage)
Is there a way to make this dynamic? To make the program generate proper positions if I set number of ROWS to 3 and COLUMS to 6? Or any other even pair.
you can translate easy...
public int getIndexOf(int x, int y){
return x + y * ROWS;
}
and revert as well...
public int getXFromIndex(int index){
return index%ROWS;
}
public int getYFromIndex(int index){
return index/ROWS;
}
Martin Frank already provided the correct answer to your question, but I'd like to present an alternative solution. Instead of serializing your rows and columns into a 1D array list, why not use a 2D array?
MemoryCard[][] cards = new MemoryCard[ROWS][COLUMNS];
Then you can access your card on row x and column y just like this:
MemoryCard card = cards[x][y];
Sounds like it would be better to use a 2D array which will be easier to maintain and visualize positions, something like
Objects[][] memoryCards;
Then to fill it you just use your loop.

Finding the average value of the color red in a BufferedImage (Java)

I want find the average red RGB-value of a MyImage (extending BufferedImage). I save the red value for each pixel in the image to an array red[]. At the end I want to sum these ut to find the average value of red. But when I run this code on a MyImage it only prints 0. How can i get this method to work properly? (The code not included here works just fine)
public class MyImage extends BufferedImage {
public MyImage(int width, int height, int imageType) {
super(width, height, imageType);
}
public void findAverageRedValue(){
int height = this.getHeight();
int width = this.getWidth();
int[] red = new int[height*width];
Map m = new HashMap();
for(int i=0; i < width ; i++)
{
for(int j=0; j < height ; j++)
{
ColorModel colorModel = this.getColorModel();
int rCol = colorModel.getRed(j*i);
red[red.length - 1] = rCol;
}
}
int sum = 0;
for(int i = 0; i < red.length; i++)
sum += red[i];
int averageRed = sum/red.length;
System.out.println(averageRed);
}
}
You're assigning elements of your array as:
red[red.length - 1] = rCol;
This will, in every possible situation, only assign the last element of the array. The length property of an array isn't like the size() of a collection; it's a static value which is based on the initialised dimension of the array.
So all but one of the array entries will be zero. Thus at the end, the sum will be between 0 and 255 - and when divided by a (likely) larger number, this comes out as zero. (There's a possible issue here in that you're doing integer division, but this is perhaps not critical).
To fix this, you'll need to change which array index you assign to. You could either keep a separate counter for the array index - or, make use of the existing i and j to do:
red[i * width + j] = rCol;
Either way, this will put each pixel's red component into a separate array location, and thus enable you to sum them correctly.
Integer division is a potential gotcha in Java, and that's what you're doing here at the end. It may be better to get the fractional average via sum / (float)red.length, though as long as you know what's happening and you're happy to have truncation to the nearest integer, this may not be necessary.

Categories