Say, I have a 1d array with 30 elements:
array1d[0] = 1
array1d[1] = 2
array1d[2] = 3
.
.
.
array1[29] = 30
How to convert the 1d array to 2d array?
Say 10x3?
array2d[0][0] = 1 array2d[0][1] =2 array2d[0][2] =3
.
.
.
array2d[9][0] = 28 array2d[9][1] =29 array2d[9][2] =30
Should I use a for loop?
But I cannot work it out.
Without writing any code for you...
Think about how big your 2d array needs to be.
Recognize that you'll need to loop over the contents of your source array to get each value into your destination array.
So it will look something like...
Create a 2d array of appropriate size.
Use a for loop to loop over your 1d array.
Inside that for loop, you'll need to figure out where each value in the 1d array should go in the 2d array. Try using the mod function against your counter variable to "wrap around" the indices of the 2d array.
I'm being intentionally vague, seeing as this is homework. Try posting some code so we can see where you get stuck.
int array2d[][] = new int[10][3];
for(int i=0; i<10;i++)
for(int j=0;j<3;j++)
array2d[i][j] = array1d[(j*10) + i];
Here a generic function to convert from 1D -> 2D array:
public int[][] monoToBidi( final int[] array, final int rows, final int cols ) {
if (array.length != (rows*cols))
throw new IllegalArgumentException("Invalid array length");
int[][] bidi = new int[rows][cols];
for ( int i = 0; i < rows; i++ )
System.arraycopy(array, (i*cols), bidi[i], 0, cols);
return bidi;
}
If you want to do the contrary (2D -> 1D), here the function:
public int[] bidiToMono( final int[][] array ) {
int rows = array.length, cols = array[0].length;
int[] mono = new int[(rows*cols)];
for ( int i = 0; i < rows; i++ )
System.arraycopy(array[i], 0, mono, (i*cols), cols);
return mono;
}
public class Test{
public static void main(String[] argv)
{
int x,y;
for(int num =0; num<81;num++)
{
if((num % 9)>0)
{
x = num/9;
y = num%9;
}else
{
x = num/9;
y = 0;
}
System.out.println("num ["+num+"]---["+x+","+y+"]");
}
}
}
/* Replace 9 by the size of single row of your 2D array */
You often will find the same problem: how to manipulate 2D array as 1D array.
I wrote a generic class Grid, that lets access objects by index or by (x,y).
See the following class and understand the idea behind it. :)
You could use the following class for data manipulation as 2D array or 1D array. Here is the code for that I wrote and use.
/**
* Grid represents a 2 dimensional grid.
*
* #param <E> the type of elements in this grid
*/
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
public class Grid<E>
{
private int size ;
private int width ;
private int height ;
private List<E> elements;
public int getCapacity()
{
return getWidth() * getHeight();
}
/**
* #return number of elements in grid. Null is also an element.
*/
public int getSize()
{
return getElements().size();
}
/**
* #param sideSize size of the grid side
*/
public Grid(int sideSize)
{
this(sideSize,sideSize);
}
/**
* #param width of the grid
* #param height of the grid
*/
public Grid(int width, int height)
{
this.width = width ;
this.height = height;
this.elements = new ArrayList<E>(
Collections.nCopies(width*height, (E)null));
}
public int getHeight()
{
return height;
}
public int getWidth()
{
return width;
}
/**
* #return all elements of the grid
*/
public List<E> getElements()
{
return elements;
}
/**
* #return iterator for a grid
*/
public Iterator<E> iterator()
{
return getElements().iterator();
}
/**
* Returns the element at position (x,y).
*
* #return the element at position (x,y)
*/
public E get(int x, int y)
{
return getElements().get(
idx(x,y));
}
/**
* Returns the element at index idx.
*
* #return the element at given index
*/
public E get(int idx)
{
return getElements().get(idx);
}
/**
* Puts an element to the position idx
*
* #param element to be added
*
* #param x position x to add element to
*
* #param y position y to add element to
*/
public void put(int x, int y, E element)
{
put(idx(x,y), element);
}
/**
* Puts an element to the position idx
*
* #param element to be added
*
* #param idx to add element at
*/
public void put(int idx, E element)
{
getElements().add(idx, element);
}
/**
* Returns the x coordinate from the index.
*
* #return x coordinate of the index
*/
public int x(int idx)
{
return idx % getHeight();
}
/**
* Returns the y coordinate from the index.
*
* #return y coordinate of the index
*/
public int y(int idx)
{
return (idx - idx % getHeight()) / getHeight();
}
/**
* Returns index of element at (x,y).
*
* #return index of the coordinates
*/
public int idx(int x, int y)
{
return y*getHeight() + x;
}
}
Here is how to use the class (see a test example):
public class TestGrid
{
public static final int SIZE = 10;
public static final Integer el1 = new Integer(2);
public static final Integer el2 = new Integer(3);
public static final Integer el3 = new Integer(3);
public static void main(String[] args)
{
Grid<Integer> grid = new Grid<>(SIZE);
assert grid.getCapacity() == SIZE*SIZE ;
assert grid.idx(0,0) == 0 ;
assert grid.idx(1,0) == 1 ;
assert grid.idx(0,1) == 10;
assert grid.idx(6,1) == 16;
assert grid.idx(9,9) == 99;
grid.put(1, el1);
assert grid.get(1) == el1 : grid.get(1);
grid.put(0, 1, el2);
assert grid.get(0,1) != el1 && el1 != el2 && grid.get(0,1) == el2;
grid.put(15, el3);
assert grid.get(5,1) == el3;
}
}
This is just a pseudo code. ROWS represent the length of the 2d array, and COLUMNS represent the length of the 1st element in the array
for(i=0; i<ROWS; i++)
for(j=0; j<COLUMNS; j++)
array2d[i][j] = array1d[ (i*COLUMNS) + j];
package com.vikrant;
import java.util.Arrays;
public class TwoD {
public static void main(String args[])
{
int a[][]=new int[4][3];
int d[]={10,20,30,40,50,60,70,80,90,100,110,120};
int count=0;
for(int i=0;i<4;i++)
{
for(int j=0;j<3;j++)
{
if(count==d.length) break;
a[i][j]=d[count];
count++;
}}
int j=0;
for (int i = 0; i<4;i++)
{
for(j=0;j<3;j++)
System.out.println(a[i][j]);
}
}}
THIS DOES THE WORK
int[] oneDArray = new int[arr.length*arr.length];
//Flatten 2D array to 1D array...
int s = 0;
for(int i = 0; i < arr.length; i ++)
for(int j = 0; j < arr.length; j ++){
oneDArray[s] = arr[i][j];
s++;
}
You can't "convert" a 1D array to a 2D array, but an array can be multi-dimensionnal when you declare it.
int myArray2d[][] = new int[10][3]
Related
We are creating a program that will return a topographic map and show the user the best way to navigate the terrain without making steep climbs or descents. For the files that I am working with, I am not sure what maximum and minimum values need to be returned. The assignment is mostly complete except for 3 errors regarding an expected return value. I've submitted the primary code that we are working with and included a link to the other files the professor has given us for the assignment.
I've tried return maxValue, return minValue, return max, return min, and a few other combinations but the issue is I'm not sure if I am supposed to be returning a value from this MapDataDrawer.java file or from one of the other two files that we have to use for the assignment from the professor.
//MapDataDrawer.java
//This is the code that is returning the error
import java.util.*;
import java.io.*;
import java.awt.*;
public class MapDataDrawer
{
private int[][] grid;
public MapDataDrawer(String filename, int rows, int cols){
// initialize grid
grid = new int[rows][cols];
//read the data from the file into the grid
File dataFile = new File(filename);
try {
Scanner dataInput = new Scanner(dataFile);
for (int i=0; i<rows; i++) {
for (int j=0; j<cols;j++) {
grid[i][j] = dataInput.nextInt();
}
}
} catch (Exception e) { e.printStackTrace();}
}
/**
* #return the min value in the entire grid
*/
public int findMin() {
// Implement this method
}
/**
* #return the max value in the entire grid
*/
public int findMax(){
// Implement this method
}
/**
* #param col the column of the grid to check
* #return the index of the row with the lowest value in the given col for the grid
*/
public int indexOfMinRow(int col){
//Implement this method
}
/**
* Draws the grid using the given Graphics object.
* Colors should be grayscale values 0-255, scaled based on min/max values in grid
*/
public void drawMap(Graphics g){
int min = findMin();
int max = findMax();
for (int i=0; i<480; i++) {
for (int j=0; j<480; j++) {
int c = (255 * (grid[i][j] - min)) / (max - min);
g.setColor(new Color(c, c, c));
g.fillRect(j, i, 1, 1);
}
}
}
/**
* Find a path from West-to-East starting at given row.
* Choose a foward step out of 3 possible forward locations, using greedy method described in assignment.
* #return the total change in elevation traveled from West-to-East
*/
public int drawLowestElevPath(Graphics g, int row){
int elevChange = 0;
// Implement this method
return elevChange;
}
private int minOfThree(int a, int b, int c) {
if ((a > b) && (a > c)) return a;
if ((b > a) && (b > c)) return b;
if ((c > a) && (c > b)) return c;
return 0;
}
}
These are the professors submitted files, of which I am unsure if I am supposed to be returning some value from one of these files or from the actual homework file (MapDataDrawer.java) https://drive.google.com/drive/folders/1siRoY1K0ngptE2rL-wscXLK8Ct7Qo1hb?usp=sharing
It also includes the topographic data we are supposed to use.
As you have filled grid:
public int findMin() {
int min = Integer.MAX_VALUE;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
int value = grid[i][j];
if (value < min) {
min = value;
}
}
}
return min;
}
jump is an array that has been initialised.
FunctionMonius3.difRandoms method returns an array
jump = FunctionMonius3.difRandoms(posMonius.length, lines * col, generator);
or
jump = Arrays.copyOf(FunctionMonius3.difRandoms(posMonius.length, lines * col, generator), v.length);
Does the first option just creates a reference that is destroyed when the method FunctionMonius3.difRandoms ends or is it ok?
* #param n - number of array elements
* #param sup - max value
* #param g - generator
public static int[] difRandom (int n, int sup, Random g){
int[] result = new int [n];
int i = 0;
while (i < result.length) {
int random = g.nextInt(sup) + 1;
if (!contidoEmParte(aleatorio,result,i)){
result[i] = random;
i++;
}
}
return result;
}
I have the following code:
public class Map {
private Random rand = new Random();
private int x, y, z;
private boolean[][][] blocks;
/**
* Creates a map object. Map objects include a 3 dimensional
* boolean array. Declared through <code>new boolean[z][y][x]</code>.
* #param x
* #param y
* #param z
*/
public Map(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
this.blocks = new boolean[this.z][this.y][this.x];
for (boolean[][] i : this.blocks) {
for (boolean[] j : i) {
for(int k = 0; k < j.length; k++) {
j[k] = (rand.nextInt(1) == 1);
}
}
System.out.println(Arrays.toString(this.blocks));
}
}
/**
* Returns the map array.
* #return
*/
public String getMap() {
return Arrays.toString(blocks);
}
}
I want to create a three-dimensional boolean array of random true/false values. However, whenever I call new Map(10, 10, 10) I get a "java.lang.NullPointerException", which means that the array is either full of null values, or is null itself.
What I want to know is how can I create this array, so I do not get this exception (nor any other exception).
EDIT: I fixed an error with setting a value for rand, but the loops still do not fill the array with booleans. I get this:
[[[Z#6d06d69c, [[Z#7852e922, [[Z#4e25154f, [[Z#70dea4e, [[Z#5c647e05, [[Z#33909752, [[Z#55f96302, [[Z#3d4eac69, [[Z#42a57993, [[Z#75b84c92]
That is because your array is not really 3D, it is an array of array of arrays. So your line
this.blocks = new boolean[this.z][this.y][this.x];
creates an array of z instances of boolean[][], all of which are null. So we need to create them explicitely:
this.blocks = new boolean[z][y][x];
for (int i = 0; i < z; i++) {
this.blocks[i] = new boolean[y][x];
for (int j = 0; j < y; j++) {
this.blocks[i][j] = new boolean[x];
for(int k = 0; k < x; k++) {
this.blocks[i][j][k] = (rand.nextInt(1) == 1);
}
}
}
System.out.println(Arrays.toString(this.blocks));
I implemented the partition method in the quicksort algorithm but i dont know if it satisfies the loop invariant that they were given to me.
public class qs {
private qs(){}
/**
* Sort an array in ascending order
* #param arr array to sor */
public static void quickSort(int[] arr){
qs(arr, 0, arr.length);
}
/**
* Sort a region of an array in ascending order.
* Elements outside the given region are unchanged.
* requires: 0 <= start <= end <= arr.length
* #param arr array to sort
* #param start start of region (inclusive)
* #param end end of region (exclusive)
*/
private static void qs(int[] arr, int start, int end){
if (end <= start+1){ //region of length 0 or 1
return;
}
int x = arr[start];
int p = partition(arr, start+1, end, x);
//now swap arr[start] with arr[p-1]
arr[start] = arr[p-1];
arr[p-1] = x;
qs(arr, start, p-1);
qs(arr, p, end);
}
/**
* Partition a region of an array.
* Rearranges elements in region so that small ones
* all have smaller indexes than the big ones.
* Elements outside the region are unchanged.
* requires: 0 <= start <= end <= arr.length
* #param arr array to partition
* #param start start of region (inclusive)
* #param end end of region (exclusive)
* #param x pivot - "small" and "big" are <x, >=x.
* #return start index (inclusive) of big elements
* in region after partition.
*/
private static int partition(
int[] arr, int start, int end, int x)
{
int l = start-1 ;
int r = end;
while (true) {
while(++l< r && arr[l] < x);
while(r-- > l && arr[r] > x);// find smaller item
if(l >= r) // if pointers cross,
break; // partition done
else {
int temp;
temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
}
}
return l;
}
public static void main(String[] args) {
int[] a = {15,8,4,8,9,6,4,1,2,5,6,4};
quickSort(a);
for (int i = 0; i < a.length; i++){
System.out.print(" "+a[i]);
}
}
}
Your code should work except one problem. Pivot that you are selecting is the starting point of the array rather than a middle point of the array. So instead assigning
int x = arr[start];
You better assign it to
int x = arr[(start + end)/2];
Your code must work.
What changes do i need to make to the partition loop if inside the partition method i want to initialise l=start or l=start+1 and end =end-1 ? If these values are initialised to l=start-1; and r=end; than the loop works fine but it does not satisfy the invariant.Any ideas?
public class qs {
private qs(){}
/**
* Sort an array in ascending order
* #param arr array to sor */
public static void quickSort(int[] arr){
qs(arr, 0, arr.length);
}
/**
* Sort a region of an array in ascending order.
* Elements outside the given region are unchanged.
* requires: 0 <= start <= end <= arr.length
* #param arr array to sort
* #param start start of region (inclusive)
* #param end end of region (exclusive)
*/
private static void qs(int[] arr, int start, int end){
if (end <= start+1){ //region of length 0 or 1
return;
}
int x = arr[start];
int p = partition(arr, start+1, end, x);
//now swap arr[start] with arr[p-1]
arr[start] = arr[p-1];
arr[p-1] = x;
qs(arr, start, p-1);
qs(arr, p, end);
}
/**
* Partition a region of an array.
* Rearranges elements in region so that small ones
* all have smaller indexes than the big ones.
* Elements outside the region are unchanged.
* requires: 0 <= start <= end <= arr.length
* #param arr array to partition
* #param start start of region (inclusive)
* #param end end of region (exclusive)
* #param x pivot - "small" and "big" are <x, >=x.
* #return start index (inclusive) of big elements
* in region after partition.
*/
private static int partition(
int[] arr, int start, int end, int x)
{
int l = start ;
int r = end-1;
while (l<r) {
while(++l< r && arr[l] < x);
while(--r > l && arr[r] > x);
if(l >= r) // if pointers cross,
break; // partition done
else {
int temp;
temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
}
}
return l;
}
public static void main(String[] args) {
int[] a = {15,8,4,8,9,6,};
quickSort(a);
for (int i = 0; i < a.length; i++){
System.out.print(" "+a[i]);
}
}
}
Pivot should be Middle point, not the starting of the array.
int x = arr[start];
Replace this line with this...
int x = arr[(start+end)/2]