Creating a symmetrical 2D array - java

I've been racking my brains over something that must be incredibly simple, as I've not seen it answered anywhere (or I'm very bad at searching).
I want to create a symmetrical 2D array, filled with random numbers from 1 to 100 inclusive... here is what I've got so far
int n = 3;
int rangeOfWeights = 100;
double[][] array = new double[n][n];
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
array[i][j] = rand.nextInt((rangeOfWeights)+1);
}
}
At the moment, this is giving results like:
44 45 32
9 31 53
25 48 74
when actually the kind of result I want is:
0 34 32
34 0 23
32 23 0

As you defined, you're trying to create a 2D array where array[i][j] == array[j][i]. You could a pair of nested loops where one iterates up to the array's size and the other up to the outer array's counter, and in each iteration set the value of the two symmetrical values:
double[][] array = new double[n][n];
for(int i = 0; i < n; i++) {
for(int j = 0; j < i; j++) {
int value = rand.nextInt((rangeOfWeights)+1);
array[i][j] = value;
array[j][i] = value;
}
}

Related

Why is the result only 81 when I try to use array

Thanks for reading my question:
public class Gugudan_array {
public static void main(String[] args) {
for(int i = 2; i<10; i++) {
for(int j = 1; j<10; j++) {
System.out.println(i * j);
}
System.out.println();
}
}
}
In the multiplication table above, result comes correctly from 2-9, however:
public class Gugudan_array {
public static void main(String[] args) {
int[] result = new int[10];
for(int h = 0; h < result.length; h++) {
for(int i = 2; i < 10; i++) {
for(int j = 1; j<10; j++) {
result[h] = (i * j);
}
}
}
for(int a = 0; a < result.length; a++) {
System.out.println(result[a]);
}
}
}
In this code with array, the result comes out only 81.
What have I done wrong?
Thank you!
I'll first explain why your code doesn't work, and then go over a correct solution:
public class Gugudan_array {
public static void main(String[] args) {
int[] result = new int[10];
for(int h = 0; h < result.length; h++) {
for(int i = 2; i < 10; i++) {
for(int j = 1; j<10; j++) {
result[h] = (i * j);
}
}
}
for(int a = 0; a < result.length; a++) {
System.out.println(result[a]);
}
}
}
The main problem lies in this chunk of code:
for(int i = 2; i < 10; i++) {
for(int j = 1; j<10; j++) {
result[h] = (i * j);
}
}
Here, you are constantly overwriting the value of result[h], so that once the loop ends and both i = 9, and j = 9, the code will execute result[h] = 9 * 9 and then continue on to the next h.
My solution:
public class Gugudan_array {
public static void main(String[] args) {
int[] result = new int[10];
for(int i = 2; i < 10; i++) {
for(int j = 1; j<10; j++) {
result[i - 2] = (i * j);
}
}
for(int a = 0; a < result.length; a++) {
System.out.println(result[a]);
}
}
}
Output:
18
27
36
45
54
63
72
81
0
0
First, notice how I completely got rid of the h loop. That is because we can make the index in terms of i. When we determine the first number, when i = 2, we want to store that number in the 0th index of our array. Similarly, when we get our second number, when i = 3, we want to store the result in the 1st index of our array.
To summarize, whenever we calculate a result, we will want to store it in the i - 2th index of our array.
Better Solution using 2D arrays:
int[][] result = new int[8][9];
for(int i = 2; i < 10; i++) {
for(int j = 1; j<10; j++) {
result[i - 2][j - 1] = (i * j);
}
}
for(int a = 0; a < result.length; a++) {
for(int b = 0; b < result[a].length; b++){
System.out.print(result[a][b] + " ");
}
System.out.println();
}
Output:
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81
Note: If you want the output to match your original code, change System.out.print(result[a][b] + " "); to System.out.println(result[a][b])
It would make the most sense to store a multiplication table in a 2D array.
This code works by mapping i * j to the [i - 2][j - 1]'th element of the 2D array, so that 2 * 1, will end up in result[0][0]
I hope this made sense! Please let me know if you need any further help or clarification!
You have to increase h variable after all iteration. Here is whole code:
public static void main(String[] args) {
int[] result = new int[10];
for (int h = 0; h < result.length; h++) {
for (int i = 2; i < 10; i++) {
for (int j = 1; j < 10; j++) {
result[h] = (i * j);
if (h < 9) {
h++;
}
}
}
}
for (int a = 0; a < result.length; a++) {
System.out.println(result[a]);
}
}
The issue is that your current setup with 3 nested loops, the outer loop runs 10 times, the middle loop runs 8 times for each other loop, and the inner loop runs 9 times for each middle loop, which gives a total of 10x8x9=720 times... but I suspect you just want 72 results like you show in your first example, so we need to remove the outer loop first for(int h = 0; h < result.length; h++) {.
Now the issue is that we need to store all 72 results but your current array only fits 10 results int[] result = new int[10];, we can solve this with a bigger array:
int[] result = new int[8 * 9]; //72 spaces
Here is a working solution with a long array and a counter that keeps track of where to store the value, note the code comments for extra details:
//Your loops calculate 8 * 9 results, so you need an array with 72 spaces
int[] result = new int[72];
//Use a variable to track the array location
int counter = 0;
//Youn only need two loops
for(int i = 2; i < 10; i++) {
for(int j = 1; j< 10; j++) {
//Save the result in the correct location
result[counter] = (i * j);
//Incriment the counter
counter++;
}
}
//Print the stored results
for(int a = 0; a < result.length; a++) {
System.out.println(result[a]);
}
Some further important reading from the official Java guide on Arrays:
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
A better solution would be to use a 2D array.

Trouble filling 2D array with values obtained from method

I'm having trouble filling a matrix with values I get by iterating through a method. I want to use a 3x3 matrix and then fill it with the values I obtain by iterating my method from 0 to 8. My idea was a for-loop but it does not work unfortunately. I would be glad if someone could help or has a link where I can look that up.
int[][] matrix = new int[3][3];
for (int i = 0; i < matrix.length; i++){
for (int j = 0; j < matrix[i].length; j++){
for(int a = 0; a < 9; a++) {
matrix[i][j] = fields.get(a).getSign().getFieldValue();
}
}
}
Correct me if I'm wrong.
The way I understood your question was you want to fill the matrix like this:
012
345
678
In that case you can do the first 2 forloops and add some maths, to get the correct numbers on every position:
int[][] matrix = new int[3][3];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
matrix[i][j] = i * matrix[i].length + j;
}
}
The way this works is for every row (i) you multiply the rownumber by the rows length (the number of columns) and add the current column to it
To iterate through a two dimensional field (e.g. a matrix), you can use two for loops:
int dimension = 3;
int [][] matrix = new int [dimension][dimension];
for (int i = 0; i < dimension; i++){
for ( int j = 0; j < dimension; j++){
matrix[i][j] = fields.get(i).get(j);
}
}
I don't exactly know how you want to retrieve the values, but your current call looks suspicious to say the least :-)
It will simply assign the same value to all ints in column j.
If you simulate your loop, this is what it looks like
i -> 0
j -> 0
matrix[0][0] -> loop over all values from field
this way you would be putting the fields.get(8) into each index in your matrix.
#Alan's answers show how to properly loop and fill a 2d matrix from a 1d matrix

How to store and change values for 2D lists?

I have a function that would sum up the rows of an array and have it displayed in one column at the beginning/end. It was initially done with a 2D array(int[][]) and it works fine. I would now like to change the input to 2D lists(List<List<Integer>>) instead of arrays. This is the function that uses int[][] that currently works:
public static void sumLeft(int[][] numbers) {
for (int i = 0; i < numbers.length; i++) {
for (int j = 1; j < numbers[i].length; j++) {
numbers[i][0] += numbers[i][j];
numbers[i][j] = 0;
}
}
}
So if I take in this array:
10 15 30 40
15 5 8 2
20 2 4 2
1 4 5 0
This would be the result:
95 0 0 0
30 0 0 0
28 0 0 0
10 0 0 0
Now I want to do the same thing, but with 2D lists, or List<List<Integer>>.
This is what I currently have:
public static void listLeft(List<List<Integer>> list) {
int sum = 0;
for (int i = 0; i < list.size(); i++) {
List<Integer> innerList = list.get(i);
for (int j = 0; j < list.get(i).size(); j++) {
sum += list.get(i).get(j);
innerList.set(0, sum);
innerList.set(j, 0);
}
}
}
If I take in the same set of numbers, it would output this:
95 0 0 0
125 0 0 0
153 0 0 0
163 0 0 0
*Notice that rows 2-4 have the wrong values.
Move sum into the for loop that spans the lists. Also, you don't need to set the first list item to sum with every item in the list; you can set it once at the end.
public static void listLeft(List<List<Integer>> list) {
for (int i = 0; i < list.size(); i++) {
int sum = 0;
List<Integer> innerList = list.get(i);
for (int j = 0; j < list.get(i).size(); j++) {
sum += list.get(i).get(j);
innerList.set(j, 0);
}
innerList.set(0, sum);
}
}

Selection sort algorithm problems

So I have this code for my selection sort:
public static void selectionSort(int[] arrayToSort){
int smallest;
for(int i = 0; i < arrayToSort.length; i++){
smallest = i;
for(int j = i+1; j < arrayToSort.length; j++){
if(arrayToSort[j] < arrayToSort[smallest]){
smallest = j;
}
if(smallest != i){
int temp = arrayToSort[i];
arrayToSort[i] = arrayToSort[smallest];
arrayToSort[smallest] = temp;
}
}
}
}
I am generating a int array with random numbers. My selection sort sometimes does sort the array, sometimes it does "almost" sort the array. The array will mostly be sorted except for a very few numbers which are in wrong places. I can't figure out what goes wrong here, any ideas?
Some test results where the array were not completely sorted:
***NON SORTED***
77
53
27
58
83
***SORTED***
27
53
77
58
83
and
***NON SORTED***
40
87
27
48
82
***SORTED***
27
40
82
48
87
You have a part of code inside the inner loop, put it outside the loop;
public static void selectionSort(int[] arrayToSort){
int smallest;
for(int i = 0; i < arrayToSort.length; i++){
smallest = i;
for(int j = i+1; j < arrayToSort.length; j++){
if(arrayToSort[j] < arrayToSort[smallest]){
smallest = j;
}
}
if(smallest != i){
int temp = arrayToSort[i];
arrayToSort[i] = arrayToSort[smallest];
arrayToSort[smallest] = temp;
}
}
}
See for instance the algorithm in Wikipedia.
I did this when i need it in college project !
references : selection algoritm with figure
public static void selectionSort(int[] arr){
for (int i = 0; i < arr.length - 1; i++)
{
int index = i;
for (int j = i + 1; j < arr.length; j++){
if (arr[j] < arr[index]){
index = j;//searching for lowest index
}
}
int smallerNumber = arr[index];
arr[index] = arr[i];
arr[i] = smallerNumber;
}
}
Here inside 2nd foor loop, if you find any elements which is less than i(or smallest) you are doing swap operation which is not required here. In selection sort, you need to get smallest element from the unsorted array and swapped with the leftmost element, and that element becomes a part of the sorted array.
Just keep swap outside of 2nd inner loop So that it only does swap operation for smallest element.
for(int i = 0; i < arrayToSort.length; i++){
smallest = i;
for(int j = i+1; j < arrayToSort.length; j++){
if(arrayToSort[j] < arrayToSort[smallest]){
smallest = j;
}
}
if(smallest != i){
int temp = arrayToSort[i];
arrayToSort[i] = arrayToSort[smallest];
arrayToSort[smallest] = temp;
}
}

Filling a two dimensional array with integers java

I wanted to write a function which should fill a two dimensional array like this:
1 -- 3 -- 5 -- 7 -- 9
3 -- 5 -- 7 -- 9 -- 11
5 -- 7 -- 9 -- 11 -- 13
7 -- 9 -- 11 -- 13 -- 15
9 -- 11 -- 13 -- 15 -- 17
Here's it what I could come up with ... by all my logic it should work, but obviously I made some mistake:
public class Array {
public static void TwoDimFill(int[] [] array, int start, int inc){
array[0] [0] = start;
for (int i = 0; i < array.length; i++){
for (int j = 0; j < array[i].length; j++){enter code here
array[i][j+1] = array[i][j] + inc;
}
array [i+1][0] = array[0][i+1];
}
}
public static void main(String[] args){
int[] [] b = new int[5] [5];
TwoDimFill(b, 1, 2);
for (int x = 0; x < b.length; x++){
for (int y = 0; y<b[x].length; y++){
TextIO.put(b[x][y]+"\t");
}
TextIO.putln();
}
}
By the way: This TextIO.class is something we use for printing, compareable to system.out ...
Edit: Answered! Thank you a lot guys, you're great!
i+1 and j+1 will be out of bounds because you loop until < length. Change it to < length -1.
for (int i = 0; i < array.length; i++){
for (int j = 0; j < array[i].length -1; j++){
array[i][j+1] = array[i][j] + inc;
}
if (i < array.length -1)
array [i+1][0] = array[0][i+1];
}
EDIT: As pointed out on comments, the last output line was incorrect. Variable i can be looped until < length, but it must be verified for the last line that the index won't get out of bounds. Corrected the code above.
There is an excess number of operations you are doing. There is a much cleaner, simpler and faster solution. Sometimes a different approach can solve the problem better.
for (int i = 0; i < array.length; i++)
for (int j = 0; j < array[i].length; j++)
array[i][j]=((i+j)<<1)+1;
You need to check if the index is out of bounds before executing the last line in your loop, as well as only making your inner loop iterate up to length-1 (since indexes for arrays in Java start at 0 and end at 1 less than their length):
for(int i = 0; i < array.length; i++) {
for(int j = 0; j < array[i].length - 1; j++) {
array[i][j + 1] = array[i][j] + inc;
}
if(i + 1 < array.length) {
array[i + 1][0] = array[0][i + 1];
}
}
This produces:
1 3 5 7 9
3 5 7 9 11
5 7 9 11 13
7 9 11 13 15
9 11 13 15 17
Note that simply clipping the outer loop to array.length-1 doesn't work (since in this case you still want the first part of the loop to execute), you'd end up with the following:
1 3 5 7 9
3 5 7 9 11
5 7 9 11 13
7 9 11 13 15
9 0 0 0 0
Bolding is mine, note the last line is obviously incorrect.
This is wrong because of array[i][j+1]. If j is the last position j+1 doesn't exist. You can try this:
public static void TwoDimFill(int[] [] array, int start, int inc){
int aux = 0;
for(int i = 0; i < array.length; i++) {
aux = start;
for(int j = 0; j < array[i].length; j++) {
array[i][j] = aux;
aux += inc;
}
start += inc;
}
}
You can do this really simply, use the following
public class TestClass {
public static void main(String args[]) {
int[][] temp = new int[5][5];
int[][] output = fill2dim(temp,1,2);
for (int i = 0; i < output.length; i++) {
System.out.println(java.util.Arrays.toString(output[i]));
}
}
public static int[][] fill2dim(int[][] arr, int start, int inc) {
int[][] output = new int[arr.length][arr[0].length];
for (int i = 0;i<arr.length;i++) {
for (int j = i;j<arr[0].length;j++) {
output[i][j] = (i+j)*inc+start;
output[j][i] = (i+j)*inc+start;
}
}
return output;
}
}
You can remove some loops by just considering the upper triangular matrix, since the lower triangular matrix will be a reflection of the upper triangle about the diagonal

Categories