Variable changes without me using it - java

I have a problem, my variable tabOffrandes change without I change this so I don't understand. This is my code:
public static int[] tri_selection(int[] tab) {
int a;
for (int i = 0; i < tab.length; i++) {
for (int j = i + 1; j < tab.length; j++) {
if (tab[i] > tab[j]){
a = tab[j];
tab[j] = tab[i];
tab[i] = a;
}
}
}
System.out.println();
return tab;
}
public static Joueur[] offrande(int[] offrandes) {
int[] tabOffrandes = offrandes;
printTab(tabOffrandes);
int[] ordreOffrande = tri_selection(offrandes);
printTab(tabOffrandes);
The terminal respond:
8 - 3 - 5 - 1
1 - 3 - 5 - 8
The function printTab just print all of the numbers in int[], I think it's not very important to show this.

The problem in your code is that you refer to the same array in the memory, even if you provide different names for them.
This is only an assumption, but what I think you are trying to do by writing:
int[] tabOffrandes = offrandes;
is to create a copy of your original array, right?
To achieve this, you must write the code as:
int[] tabOffrandes = Arrays.copyOf(offrandes, offrandes.length);
This way, your original offrandes array will not be affected when you call the tri_selection function.
Not related to your question, but it might help you in the future. I'm not sure what's your implementation for printTab function. I assume that you manually iterate through the array and print the items? Just wanted to let you know that there is a shorter solution, by using Arrays.toString(...), in case you didn't know:
System.out.println(Arrays.toString(tabOffrandes));

Related

How to copy a 2-dimensional array in java

I just began studying java. One of the tasks was to create a function to create a reverse 2-dimensional array, for example, if the input array was {1,2}{3,4}, the new array must be {4,3}{2,1}. The code below is the method I created. The problem is that the old array d is affected by the loop along with c, so, in this case, it copies half of the values into c, but also replaces the last half of d, so the second half of c is just a mirrored first half, basically, in the example case both c and d will be like this in the end: {4,3}{3,4}. I checked c==d and c.equals(d) after cloning, both show false.
Also, I tried using Arrays.copy, the result was the same. Plus I want the method to work on the arrays that can have their sub-arrays with different lengths, for example, {1,2}{3}{4,5}, and I don't know if it'll work on such arrays.
static int[][] reversematrix(int[][] d) {
int[][] c = d.clone();
for (int i = d.length-1, x = 0; i >= 0; x++, i--) {
for (int j = d[i].length-1, y = 0; j>=0; y++, j--) {
c[x][y] = d[i][j];
}
}
return c;
Can you tell me how to make d(imput array) unaffected by the method/loop? I think the problem is in copying, so I'd love to know a proper way of copying a 2D array into a new object, but if it is in something else, please tell me waht it is.
UPD: Thanks to #sascha the solution was found. Here's the code if someone is interested:
static int[][] reversematrix(int[][] d) {
int[][] c = new int[d.length][];
for (int i = d.length-1, x = 0; i >= 0; x++, i--) {
c[x] = new int[d[i].length];
for (int j = d[i].length-1, y = 0; j>=0; y++, j--) {
c[x][y] = d[i][j];
}
}
return c;
}

Two sum - Doesn't work

Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Consider input [3,2,4] and target is 6. I added (3,0) and (2,1) to the map and when I come to 4 and calculate value as 6 - 4 as 2 and when I check if 2 is a key present in map or not, it does not go in if loop.
I should get output as [1,2] which are the indices for 2 and 4 respectively
public int[] twoSum(int[] nums, int target) {
int len = nums.length;
int[] arr = new int[2];
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
for(int i = 0;i < len; i++)
{
int value = nums[i] - target;
if(map.containsKey(value))
{
System.out.println("Hello");
arr[0] = value;
arr[1] = map.get(value);
return arr;
}
else
{
map.put(nums[i],i);
}
}
return null;
}
I don't get where the problem is, please help me out
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice. Consider input [3,2,4] and target is 6. I added (3,0) and (2,1) to the map and when I come to 4 and calculate value as 6 - 4 as 2 and when I check if 2 is a key present in map or not, it does not go in if loop.
Okay, let's take a step back for a second.
You have a list of values, [3,2,4]. You need to know which two will add up 6, well, by looking at it we know that the answer should be [1,2] (values 2 and 4)
The question now is, how do you do that programmatically
The solution is (to be honest), very simple, you need two loops, this allows you to compare each element in the list with every other element in the list
for (int outter = 0; outter < values.length; outter++) {
int outterValue = values[outter];
for (int inner = 0; inner < values.length; inner++) {
if (inner != outter) { // Don't want to compare the same index
int innerValue = values[inner];
if (innerValue + outterValue == targetValue) {
// The outter and inner indices now form the answer
}
}
}
}
While not highly efficient (yes, it would be easy to optimise the inner loop, but given the OP's current attempt, I forewent it), this is VERY simple example of how you might achieve what is actually a very common problem
int value = nums[i] - target;
Your subtraction is backwards, as nums[i] is probably smaller than target. So value is getting set to a negative number. The following would be better:
int value = target - nums[i];
(Fixing this won't fix your whole program, but it explains why you're getting the behavior that you are.)
This code for twoSum might help you. For the inputs of integer array, it will return the indices of the array if the sum of the values = target.
public static int[] twoSum(int[] nums, int target) {
int[] indices = new int[2];
outerloop:
for(int i = 0; i < nums.length; i++){
for(int j = 0; j < nums.length; j++){
if((nums[i]+nums[j]) == target){
indices[0] = i;
indices[1] = j;
break outerloop;
}
}
}
return indices;
}
You can call the function using
int[] num = {1,2,3};
int[] out = twoSum(num,4);
System.out.println(out[0]);
System.out.println(out[1]);
Output:
0
2
You should update the way you compute for the value as follows:
int value = target - nums[i];
You can also check this video if you want to better visualize it. It includes Brute force and Linear approach:

Produce repmat() method using java

we have the repmat(arr,2,1,2) method in matlab produce a format which is :
arr = [6,3,9,0];
L(:,:,1) =
6 3 9 0
6 3 9 0
L(:,:,2) =
6 3 9 0
6 3 9 0
the java code that i tried to produce same format is
class test24{
public static void main ( String [] args ) {
int[] arr = {6,3,9,0};
test24 test = new test24();
System.out.println(Arrays.deepToString(test.repmat(arr,2,1,2)));
}
public static int[][][] repmat (int[] array, int rows, int columns, int depth)
{
int arrayColumns = array.length;
int resultColumns = arrayColumns * columns;
int[][][] result = new int[rows][resultColumns][depth];
int z = 0;
for (int d = 0; d < depth; d++)
{
for (int r = 0; r < rows; r++)
{
for (int c = 0; c < resultColumns; c++)
{
result[r][c][d] = array[z++];
if (z >= arrayColumns)
{
z = 0;
}
}
}
}
return result;
}
}
the the result from the java code is :
[[6,6],[3,3],[9,9],[0,0]],[[[6,6],[3,3],[9,9],[0,0]]???
please any suggestion
I believe that the depth argument causes that each value within the array has two values (int[][][] result = new int[rows][resultColumns][depth]; would become (given the inputs rows=2, columns=1 and depth=2 and an initial array of 4) new int[2][1][2]).
Not entirely sure what the repmat method exactly should do put it might be that changing the creation of the array into int[][][] result = new int[depth][rows][resultColumns]; fixes the issue.
I imagine that this is because MATLAB used column-major indexing whereas Java uses Iliffe vectors. So MATLAB stores multidimensional vectors using a single contiguous block of memory where Java stores an array of pointers and each pointer points to another array.
It's difficult to tell exactly what the Java data-structure your code resulted in was. Do you think maybe you could rather post a screen shot from a debugger? What you have now does not look correct, the brackets don't even match.
At a guess though, I would suggest that you maybe change this line
result[r][c][d] = array[z++];
To something more like
result[d][r][c] = array[z++];
Or possibly to even alter the inner loop to something like
for (int c = 0; c < columns; c++) {
result[d][r][c] = array;
}

Transposing Values in Java 2D ArrayList

Good evening all,
I'm trying to write a method that creates and returns a 2D array whose elements in each location are the same as the elements in the mirror image location of the parameter array. Unfortunately, no matter what pair of numbers I enter into the method call I get an "out of bounds" error in my compiler. Below is my program. Tell me where I've gone wrong! Thanks!
public static int[][] transpose(int [][] a) {
int r = a.length;
int c = a[r].length;
int [][] t = new int[c][r];
for(int i = 0; i < r; ++i) {
for(int j = 0; j < c; ++j) {
t[j][i] = a[i][j];
}
}
return t;
}
}
Arrays in java are 0 based, change your assignment to c to :
int c = a[r - 1].length;
#Suraj is correct, however you must assume the 2D array is rectangular, in which case it is sightly more efficient to change line 3 to:
int c = a[0].length;
#Kris answer text is correct however code sample is wrong line.
Note this error is a reproduction of a broken "answer" posted in "Yahoo Answers": http://answers.yahoo.com/question/index?qid=20080121204551AAn62RO
Your problem lies in line two: a[r].length returns the number of columns, but arrays are indexed from 0. You should adjust accordingly:
int r = a.length - 1;

Calling arrays from other methods in a different class

I need help dealing with an array in my java program. in my first class, "test", I set 4 variables and then send them to my other class (test2).
arr[i] = new test2(id, fname, lname, case);
at that point, variables are set and then I want to return those variables. So in the test2 class, I have a method that strictly returns one of those variables
public int getId(){
return id;
}
I understand this is a little stupid, but professor gets what professor wants I guess. What I want to do now is in my main method in "test" I want to retrieve that variable and sort the array based on that int. Unfortunately, I have to create my own sort function, but I think this would work for what I want to do.
for(j = 0; j < arr.length; j++){
int indexMin =j;
for(i = j; i < arr.length;i++){
if(arr[i] < arr[indexMin]){
indexMin = i;
}
}
int tmp = arr[j];
arr[j] = arr[indexMin];
arr[indexMin] = tmp;
}
I appreciate any help anyone could provide.
Thank you
So a few comments:
-Your loop looks like this:
for(i = j; i < arr.length; i++)
You should be declaring
for(int i = j; i< arr.length; i++);
Either you hadn't declared i yet, which would give you a compilation error, or you declared i earlier which is not ideal...you avoid bugs better by declaring variables as locally as possible.
-In this line you directly compare objects:
if(arr[i] < arr[indexMin]){
but if I understand your intent correctly, you want to be comparing the IDs, so this should look like
if(arr[i].getId() < arr[indexMin].getId()){
-It looks like arr is an array of test2 objects, but you assign one to an int for your swapping code:
int tmp = arr[j];
This should be
test2 tmp = arr[j];
As far as your algorithm, why don't you get your code up and running and then try testing with a few results. What about 4 objects with IDs 1, 2, 3 and 4? How about 4, 3, 2, and 1? You'll learn more by playing around with it manually than if I tell you an algorithm here. Don't be afraid to add some statements that help you see exactly what's going on when. For example, maybe you might change the last 4 lines to look like:
System.out.println("About to swap id " + arr[j].getId() + " from index " + j + " with minimum " + arr[indexMin].getId() + " at index " + indexMin);
test2 tmp = arr[j];
arr[j] = arr[indexMin];
arr[indexMin] = tmp;
This will help you sooner get to the bottom of what's happening when in your program, and don't be afraid to add more similar stuff.
Make Test2 implements Comparable<Test2> and use java.util.Arrays.sort(Object[]) instead.
The compareTo(Test2) would look something like this:
#Override int public compareTo(Test2 other) {
return
(this.id < other.id) ? -1 :
(this.id > other.id) ? +1 :
0;
}
Even better is if you can switch to List<Test2> (Effective Java 2nd Edition: Item 25: Prefer lists to arrays).
See also
Java Integer: what is faster comparison or subtraction?
DO NOT be tempted to be "clever" and use this.id - other.id. This comparison-by-subtraction trick is broken.
Java Naming convention
Class names should be nouns, in mixed case with the first letter of each internal word capitalized.
If you have to implement your own sort, then in place of arr[i] < arr[indexMin], you want arr[i].getId() < arr[indexMin].getId(). This assumes that it was declared Test2[] arr;
If for some reason it was declared as Object[] arr instead, then you'd just need to cast them to Test2 before you can invoke getId().
((Test2) arr[i]).getId() < ((Test2) arr[indexMin]).getId()
You'd also want to declare Test2 tmp instead of int tmp for the swap.
As for printing, you can use a for-each loop:
for (Test2 t : arr) {
System.out.println(t);
}
This assumes that Test2 has #Overridepublic String toString() that is sensible for printing, but otherwise you can access the member methods individually.
See also
Java language guide/for-each loop

Categories

Resources