How to pass a double array(boolean[][]) between activities? - java

I can't see to get a double boolean array to pass through to the another activity. I use putExtra and when I retrieve it and cast it to boolean[][], it states that it can not cast and crashes. Boolean[] works however.
How would I go about passing a boolean[][] between activities?

If you absolutely need a boolean[][] (and can't do this with just a flat boolean[] array passed to Parcel.writeBooleanArray()), then the formal way to do this is to wrap it in a Parcelable class and do the marshalling/unmarshalling there.
I'll sketch out the code, though this is not tested so there are certainly to be some issues.
public class BooleanArrayArray implements Parcelable {
private final boolean[][] mArray;
public BooleanArrayArray(boolean[][] array) {
mArray = array;
}
private BooleanArrayArray(Parcelable in) {
boolean[][] array;
final int N = in.readInt();
array = new boolean[][N];
for (int i=0; i<N; i++) {
array[i] = in.createBooleanArray();
}
mArray = array;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel out, int flags) {
final int N = mArray.length;
out.writeInt(N);
for (int i=0; i<N; i++) {
out.writeBooleanArray(mArray[i]);
}
}
public static final Parcelable.Creator<BooleanArrayArray> CREATOR
= new Parcelable.Creator<BooleanArrayArray>() {
public BooleanArrayArraycreateFromParcel(Parcel in) {
return new BooleanArrayArray(in);
}
public BooleanArrayArray[] newArray(int size) {
return new BooleanArrayArray[size];
}
};
}

If you really require a 2-dimensional array, you can easily convert a 2-dimensional array into a single dimensional array for passing between Activities like so:
public boolean[] toOneDimension(boolean[][] input){
boolean[] output = new boolean[input.length * input[0].length];
for(int i = 0; i < input.length; i++){
for(int j = 0; j < input[i].length; j++){
output[i*j] = input[i][j];
}
}
return output;
}
which you can then build back into a 2-dimensional array like so:
public boolean[][] toTwoDimensions(int dimensions, boolean[] input){
boolean[][] output = new boolean[input.length / dimensions][dimensions];
for(int i = 0; i < input.length; i++){
output[i/dimensions][i % dimensions] = input[i];
}
return output;
}
then use like so:
public static void main(String[] args){
int size = 10;
Random rand = new Random();
Tester tester = new Tester(); //example code holder
boolean[][] value = new boolean[size+1][size];
for(int i = 0; i < size+1; i++){
for(int j = 0; j < size; j++){
value[i][j] = rand.nextBoolean();
}
}
boolean [][] output = tester.toTwoDimensions(size, tester.toOneDimension(value));
for(int i = 0; i < size+1; i++){
for(int j = 0; j < size; j++){
assert value[i][j] == output[i][j];
}
}
}
The only requirement is that you need to know the dimension of your array before you flattened it.

This is old, but helped me a lot, so I wanted to share my findings.
I used Parcelabler to make my Object Class Parcelable(Because everything I read, was written in martian to me), then I used #John Ericksen answer to implement it in my Object Class and some methods to make my life easier flattenMultiDimensionalArray and restoreMultiDimensionalArray and the final result.
For a 2 Dimensional Array
MultiDimensionalArray .java
public class MultiDimensionalArray implements Parcelable {
private int[][] multiDimensionalArray;
//Any other Variables, Objects
public MultiDimensionalArray() {
}
public MultiDimensionalArray(int[][] multiDimensionalArray) {
this.multiDimensionalArray = multiDimensionalArray;
//Any other Variables, Objects
}
public int[][] getMultiDimensionalArray() {
return multiDimensionalArray;
}
public void setMultiDimensionalArray(int[][] multiDimensionalArray) {
this.multiDimensionalArray = multiDimensionalArray;
}
protected MultiDimensionalArray(Parcel in) {
int rows = in.readInt();
int columns = in.readInt();
int[] transitionalArray = in.createIntArray();
multiDimensionalArray = restoreMultiDimensionalArray(transitionalArray, rows, columns);
//Any other Variables, Objects
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
int rows = multiDimensionalArray.length;
int columns = multiDimensionalArray[rows - 1].length;
int[] transitionalArray = flattenMultiDimensionalArray(multiDimensionalArray);
dest.writeInt(rows);
dest.writeInt(columns);
dest.writeIntArray(transitionalArray);
//Any other Variables, Objects
}
public static final Creator<MultiDimensionalArray> CREATOR = new Creator<MultiDimensionalArray>() {
#Override
public MultiDimensionalArray createFromParcel(Parcel in) {
return new MultiDimensionalArray(in);
}
#Override
public MultiDimensionalArray[] newArray(int size) {
return new MultiDimensionalArray[size];
}
};
private int[] flattenMultiDimensionalArray(int[][] sourceCard) {
int k = 0;
int[] targetCard = new int[sourceCard.length * sourceCard[sourceCard.length - 1].length];
for (int[] aSourceCard : sourceCard) {
for (int anASourceCard : aSourceCard) {
targetCard[k] = anASourceCard;
k++;
}
}
return targetCard;
}
private int[][] restoreMultiDimensionalArray(int[] sourceCard, int rows, int columns) {
int k = 0;
int[][] multiDimensionalArray = new int[rows][columns];
for (int i = 0; i < multiDimensionalArray.length; i++) {
for (int j = 0; j < multiDimensionalArray[multiDimensionalArray.length - 1].length; j++) {
multiDimensionalArray[i][j] = sourceCard[k];
k++;
}
}
return multiDimensionalArray;
}
}

Related

How would I pass a primitive instead of an array pointer

I have a school assignment where I need to create a very basic clone of ArrayList in java. It only needs to work with strings and have minimal functionality (size, add, get). This is what I have so far. I realise that there is probably many things that could be improved, but right now I am trying to work on this error
Exception in thread "main" java.lang.NullPointerException
at pt2.ArrayListMine.expand(ArrayListMine.java:13)
at pt2.ArrayListMine.add(ArrayListMine.java:32)
at pt2.Driver.main(Driver.java:21
I think the problem is that when I call expand() instead of moving the strings from array to backup and then backup to array it is passing pointers, so after I call it I effectivly have array pointing to backup pointing to array. Im not shure if/how I could force it to pass the string instead of the pointer so I am hoping I can get some advice. Thanks!
package pt2;
public class ArrayListMine {
private String[] array;
private String[] backup;
private int array_size = 0;
public void ArrayListMine() {
array = new String[10];
}
private void expand() {
if(array_size == array.length) {
for(int l = 0; l < array.length; l++) {
backup[l] = array[l];
}
int new_size = (int) (array.length * 2);
array = new String[new_size];
for(int l = 0; l < backup.length; l++) {
array[l] = backup[l];
}
}
}
public int size() {
return array_size;
}
public void add(String value) {
array_size = array_size + 1;
System.out.println(array_size);
expand();
array[array_size - 1] = value;
}
public String get(int index) {
return array[index];
}
}
array is null. Because this
public void ArrayListMine() {
array = new String[10];
}
is not a constructor. Remove the void. Like,
public ArrayListMine() {
array = new String[10];
}
Next, use backup = Arrays.copyOf(array, array.length) to copy array to backup. Because this
backup[l] = array[l];
will also blow-up.
Initialise the back up with the array size before copying.
backup = new String[array.length]; in side expand method before copying to it.
public class ArrayListMine {
private String[] array;
private String[] backup;
private int array_size = 0;
public ArrayListMine() {
array = new String[10];
}
private void expand() {
if(array_size == array.length) {
backup = new String[array.length];
for(int l = 0; l < array.length; l++) {
backup[l] = array[l];
}
int new_size = (int) (array.length * 2);
array = new String[new_size];
for(int l = 0; l < backup.length; l++) {
array[l] = backup[l];
}
}
}
public int size() {
return array_size;
}
public void add(String value) {
array_size = array_size + 1;
System.out.println(array_size);
expand();
array[array_size - 1] = value;
}
public String get(int index) {
return array[index];
}
public static void main(String[] args) {
ArrayListMine arrayListMine = new ArrayListMine();
for(int i=0;i<=20;i++) {
arrayListMine.add("test "+i);
}
}
}
and further you can replace your for loop with System.arrayCopy
private void expand() {
if(array_size == array.length) {
backup = new String[array.length];
System.arraycopy(array, 0, backup, 0, array_size);
/*for(int l = 0; l < array.length; l++) {
backup[l] = array[l];
}*/
int new_size = (int) (array.length * 2);
array = new String[new_size];
/*for(int l = 0; l < backup.length; l++) {
array[l] = backup[l];
}*/
System.arraycopy(backup, 0, array, 0, array_size);
}
}

Multi class array modification

3 questions in three days (I wish I could fix my problems alone) and today is still about my Sudoku project. I'm working on building a Sudoku game in Java and am working with other people who have programmed various parts of the project and right now we are trying to join together the Sudoku solver class with the JFrame class which makes it all pretty (Or it will at one point) but right now I'm having an issue with the way my 2D arrays are working (more like aren't). Below is the code where I call the solver and feed it into a lot of methods to do things:
public class FenetreGrille extends JFrame implements ActionListener{
public static int [][] NOMBRES_DEBUT;
public static int [][] GRILLE_MODIF = new int[9][9];
public int [][] GRILLE_FINALE = new int[9][9];
public static final int TAILLE = 9;
public static int TAILLECASE = 60;
public static int COTEGRILLE ;
public FenetreGrille(int [][] t){
NOMBRES_DEBUT = t;
GRILLE_MODIF = NOMBRES_DEBUT;
GRILLE_FINALE = NOMBRES_DEBUT;
COTEGRILLE = TAILLE * TAILLECASE;
SudokuBackTrack sbt = new SudokuBackTrack(GRILLE_FINALE);
// Here is the problem ^^^^^
// More code below that shouldn't be important...
}
And here is the SudokuBackTrack class:
public class SudokuBackTrack{
public static int[][] grille;
public static int[][] grilleResolu;
public static int[][] grillePos;
public static boolean[][] existeSurLigne = new boolean[9][9];
public static boolean[][] existeSurColonne = new boolean[9][9];
public static boolean[][] existeSurBloc = new boolean[9][9];
public final static int taille = 9;
public static ArrayList<Case> valParCase;
public SudokuBackTrack(int[][] t) {
grille = t;
grilleResolu = grille;
valParCase = listeValPossibles(grilleResolu);
tableauxExistence(grilleResolu);
backtracking(0, grilleResolu);
}
public static ArrayList<Case> listeValPossibles(int[][] temp) {
ArrayList<Case> t = new ArrayList<Case>();
for (int i=0; i<9; i++){
for (int j=0; j<9; j++){
if(temp[i][j] == 0) {
int pos = i*taille+j;
t.add(valeursPossibles(pos, temp));
}
}
}
Collections.sort(t);
return t;
}
public static Case valeursPossibles(int pos, int[][] t) {
int i = pos/9;
int j = pos%9;
int valPossibles = 9;
for(int s=1; s<=9; s++) {
if(!absentSurLigne(s, i, t) || !absentSurColonne(s, j, t) || !absentDansBloc(s, i, j, t)) {
valPossibles--;
}
}
Case a = new Case(pos, valPossibles);
return a;
}
public static boolean absentSurLigne(int k, int i, int[][] t) {
for (int j=0; j < 9; j++) {
if (t[i][j] == k) {
return false;
}
}
return true;
}
public static boolean absentSurColonne(int k, int j, int[][] t) {
for (int i=0; i < 9; i++) {
if (t[i][j] == k) {
return false;
}
}
return true;
}
public static boolean absentDansBloc(int k, int i, int j, int[][] t) {
int _i = i-(i%3); // ou encore : _i = 3*(i/3);
int _j = j-(j%3); // ou encore : _j = 3*(j/3);
for (i=_i; i < _i+3; i++) {
for (j=_j; j < _j+3; j++) {
if (t[i][j] == k) {
return false;
}
}
}
return true;
}
public static void tableauxExistence(int[][] t) {
for (int i=0; i < 9; i++) {
for (int j=0; j < 9; j++) {
existeSurLigne[i][j] = existeSurColonne[i][j] = existeSurBloc[i][j] = false;
}
}
int k;
for (int i=0; i < 9; i++) {
for (int j=0; j < 9; j++) {
if ((k = t[i][j]) != 0) {
existeSurLigne[i][k-1] = existeSurColonne[j][k-1] = existeSurBloc[3*(i/3)+(j/3)][k-1] = true;
}
}
}
}
public static boolean backtracking(int index, int[][] t) {
if(index == valParCase.size()) {
return true;
}
int i = (valParCase.get(index).position)/9;
int j = (valParCase.get(index).position)%9;
for(int k = 0; k < 9; k++) {
if(!existeSurLigne[i][k] && !existeSurColonne[j][k] && !existeSurBloc[3*(i/3)+(j/3)][k]){
// Ajoute k aux valeurs enregistrées
existeSurLigne[i][k] = existeSurColonne[j][k] = existeSurBloc[3*(i/3)+(j/3)][k] = true;
if(backtracking(index+1, t)){
// Ecrit le choix valide dans la grille
t[i][j] = k+1;
return true;
}
// Supprime k des valeurs enregistrées
existeSurLigne[i][k] = existeSurColonne[j][k] = existeSurBloc[3*(i/3)+(j/3)][k] = false;
}
}
t[i][j] = 0;
return false;
}
As mentioned above, my problem is that when I create an instance of my SudokuBackTrack class using the 2D Array GRILLE_FINALE, all my 2D Arrays NOMBRES_DEBUT, GRILLE_MODIF and GRILLE_FINALE become solved Sudoku grids whereas all I want is for GRILLE_FINALE to become the solved version, not all 3. I've tried debugging the codes but I haven't found anything and since it's a mixture of codes from different people, I don't know how they each created their parts. I've modified the attribute types and tried all sorts of fancy things but non worked and I'm out of ideas and mainly time... Thanks in advance and sorry for the huge question and code.
You're placing the same instance of the 2D array into NOMBRES_DEBUT, GRILLE_MODIF, GRILLE_FINALE. I think what you're looking to do is to place a copy NOMBRES_DEBUT into GRILLE_MODIF and GRILLE_FINALE.
They way you have it set up now, whever you make a modification to any of the 3 arrays, you will end up modifying all 3 because all 3 point to the same array in memory.

Determining vectors array length

public class Matrix {
public static int a = 0;
public static int b = 0;
public double myArray[][];
public Matrix(double a[][]) {
this.myArray = a;
}
public Matrix(int b, Vector... vectors) {
double myArray[][] = new double[vectors.length][];
int row = vectors.length;
Matrix.a = row;
int column = vectors[0].getYourArray().length;
Matrix.b = column;
for (int i = 0; i < row; i++) {
myArray[i] = new double[row];
}
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
if (b == 0) {
double[] a = vectors[i].getYourArray();
myArray[i][j] = a[j];
} else {
myArray[j][i] = vectors[i].getYourArray()[j];
}
}
}
}
public class Vector {
double yourArray[];
public double[] getYourArray() {
return yourArray;
}
public void setYourArray(double[] yourArray) {
this.yourArray = yourArray;
}
public Vector(double... yourArray) {
this.yourArray = yourArray;
}
}
}
I create 2 vectors array and send them into vector class to make an array which includes these two vectors parameters and then send to matrix class to create matrices with dimension of vector arrays
The problem is that how can i determine the rows and columns of new matrix?
I cannot write a proper code guys please help me
As you see it in your code:
1-th dimension: vectors.length
2-th dimension: vectors[0].getYourArray().length
Normally you also have to ensure, that for all vectors[0].getYourArray() the length is the same.

Sorting arrays of the same size according to one array

I have n arrays of the same length (say m). The arrays represent different properties of the same m logical objects and I want to sort all the arrays according to one (or more) property. What's an idiomatic or anyway compact way in Java to do this? I came up with the below, which is very verbose.
To give an idea about what I'm looking for, in Python you can just say zip(size, weight).sort, and other languages allow you to get the rank of the key array(s), which you can then apply to all the arrays.
Use of widespread utilities like Apache Commons welcome, but obviously a solution based on Java libraries would be preferred.
import java.util.*;
class Box {
public int size;
public int weight;
Box( int size, int weight ){
this.size = size;
this.weight = weight;
}
}
class SizeComparator implements Comparator<Box> {
#Override
public int compare(Box a, Box b) {
return a.size < b.size ? -1 : a.size == b.size ? 0 : 1;
}
}
public class SortArrays {
public static void main(String[] args) {
int[] size = {5,3,6,2,4,4,2};
int[] weight = {9,7,8,3,5,2,5};
List<Box> boxes = new ArrayList<Box>();
for( int i = 0; i < size.length; ++i ) {
boxes.add( new Box( size[i], weight[i] ) );
}
Collections.sort( boxes, new SizeComparator() );
int[] sortedSizes = getSizes( boxes );
int[] sortedWeights = getWeights( boxes );
System.out.println(Arrays.toString(sortedSizes));
System.out.println(Arrays.toString(sortedWeights));
}
private static int[] getSizes( List<Box> boxes ) {
int[] result = new int[boxes.size()];
for( int i = 0; i < boxes.size(); ++i ) {
result[i] = boxes.get(i).size;
}
return result;
}
private static int[] getWeights( List<Box> boxes ) {
int[] result = new int[boxes.size()];
for( int i = 0; i < boxes.size(); ++i ) {
result[i] = boxes.get(i).weight;
}
return result;
}
}
No need to create a containing Object unless you just want to wrap an array.
public static void sortMultiArrays(int[] ... index) {
// merge arrays
List<int[]> zip = new ArrayList<int[]>(index[0].length);
for(int i = 0; i<index[0].length;i++){
int[] e = new int[index.length];
for(int j = 0; j<index.length;j++){
e[j] = index[j][i];
}
zip.add(e);
}
// sort by first index
Collections.sort(zip,new ArrayComparator());
// demerge arrays
for(int i = 0; i<zip.size();i++) {
int[] ints = zip.get(i);
for (int j = 0;j<ints.length;j++) {
index[j][i] = ints[j];
}
}
}
private static class ArrayComparator implements Comparator<int[]>{
#Override
public int compare(int[] a, int[] b) {
return a[0] < b[0] ? -1 : a[0] == b[0] ? 0 : 1;
}
}

Why my selection sort doesn't sort at all?

I am trying to run selection sort to see how it work and apparently, the code that I have doesnt work as expected, can someone help me point out what i did wrong?
I know the thing goes wrong at swapping part, but i am not sure why.
public class SortingAlgorithm
{
private long timeRun;
public SortingAlgorithm()
{
timeRun = 0;
}
public long getTimeRun()
{
return timeRun;
}
public void setTimeRun(long timeRun)
{
this.timeRun = timeRun;
}
private void swap(int a, int b, int[] arrB)
{
int temp = arrB[a];
arrB[a] = arrB[b];
arrB[b] = temp;
}
public int[] selection(int[] arr, int length)
{
long startTime = System.nanoTime();
for(int i= 0; i<length-1; i++)
{
for(int k = i+1; k<length; k++)
{
if(arr[i] > arr[k])
{
swap(arr[i], arr[k], arr);
}
}
}
timeRun = System.nanoTime() - startTime;
return arr;
}
}
Here is the driver:
import java.util.*;
public class Driver
{
private static int length = 10;
private static int[] arr = new int [length];
public static void main(String [] args)
{
Random rand = new Random();
//seed the array
for(int counter = 0; counter < length ;counter++)
{
arr[counter] = rand.nextInt(10);
}
SortingAlgorithm tool = new SortingAlgorithm();
arr = tool.selection(arr, length);
for(int i = 0; i < length ;i++)
{
System.out.println(arr[i]);
}
System.out.println(tool.getTimeRun());
}
}
When you call swap, you pass in array elements:
swap(arr[i], arr[k], arr);
But your function expects the indexes to the array. You should be invoking it like this:
swap(i, k, arr);

Categories

Resources