Array gets overwritten for no apparent reason - java

Problem
I have written a loop in which I fill an array with Sum objects. Everything works fine, but as soon as the loop gets to the next iteration it overwrites the first index of the array.
What have I tried
I tried to see if maybe my problem resides in a different piece of code (such as my Sum class). But could not find anything that would disturb the loop.
I tried to find other variables with the same name (even in other methods, since I was desperate) and see if I maybe changed my iterator somewhere else. I couldn't find anything related to that.
I tried looking around on the internet and SO to find something related to accidentally overwriting arrays but couldn't find anything either.
Code
public Task(Object[] parameters)
{
this.number_of_sums = Integer.parseInt((String)parameters[0]);
this.variables_per_sum = Integer.parseInt((String)parameters[1]);
this.sum_parameters = new Object[this.variables_per_sum];
this.sums = new Sum[this.number_of_sums];
int z = 0;
for(int i = 0; i < this.number_of_sums; i++)
{
int x = 0;
for(int j = (2 + z); j < ((this.variables_per_sum + 2) + z); j++)
{
this.sum_parameters[x] = parameters[j];
x++;
}
this.sums[i] = new Sum(this.sum_parameters);
System.out.println("Index 0: "+sums[0]); //1st iteration: 1 + 1 //2nd iteration: 2 - 1
System.out.println("Index 1: "+sums[1]); //1st iteration: null //2nd iteration: 2 - 1
z += this.variables_per_sum;
}
}
Expectations
I'm expecting the output of 1 + 1 and 2 - 1. I am however getting the following: 2 - 1 and 2 - 1 when I'm done.
If anyone spots anything I'm doing wrong or would like to see more information or code on my side please say so. Thanks in advance.

I'm going to assume the Sum class doesn't store its sum, but instead computes it from the array it was constructed with whenever it's needed.
It looks like all the Sum objects will share the same array -- you're passing the same reference every time you construct a Sum. Furthermore, every time you loop over j you overwrite the contents of that array.
So when everything is done, all the sums are the same.
You should be able to get around this by giving each Sum a different sum_parameters:
public Task(Object[] parameters)
{
this.number_of_sums = Integer.parseInt((String)parameters[0]);
this.variables_per_sum = Integer.parseInt((String)parameters[1]);
this.sums = new Sum[this.number_of_sums];
int z = 0;
for(int i = 0; i < this.number_of_sums; i++)
{
Object[] sum_parameters = new Object[this.variables_per_sum];
int x = 0;
for(int j = (2 + z); j < ((this.variables_per_sum + 2) + z); j++)
{
sum_parameters[x] = parameters[j];
x++;
}
this.sums[i] = new Sum(sum_parameters);
System.out.println("Index 0: "+sums[0]); //1st iteration: 1 + 1 //2nd iteration: 2 - 1
System.out.println("Index 1: "+sums[1]); //1st iteration: null //2nd iteration: 2 - 1
z += this.variables_per_sum;
}
}

Each one of your Sum objects is constructed with this.sum_parameters as a parameter:
this.sums[i] = new Sum(this.sum_parameters);
When sum_parameters is modified in each iteration of the outer loop, it changes internally in the objects constructed around references to it.
You should make an internal copy of sum_parameters in each Sum object.

Related

Java code 1+ issue

problem with Java code.
import java.util.Random;
public class arrayTable {
public static void main (String[] args) {
System.out.println("Index\t + Value");
int Array[] = new int[10];
Random Object = new Random();
int Values;
// Assigning random values to each element of array
for(int i=0; i<Array.length;i++) {
Values= (1+Object.nextInt(50));
Array[i] = Values;
}
for(int j=0;j<Array.length;j++) {
System.out.println(j + "\t" + Array[j]);
}
}
}
Here with this code i wrote (1+) next to the object so the index should start at 1, however when ever i run the code at always starts at index 0, and it does not matter if i type 2+ or 3+ pr whatever. Could anyone be helpful with pointing out the problem with the code.
thank you in advance.
i wrote (1+) next to the object so the index should start at 1
You wrote 1+ next to the value not the index!
So, what you were doing was:
array[0] = 50 + 1;
Instead of:
array[0 + 1] = 50;
If you wanted to start from index 1 you should write it here:
Array[i + 1] = Values;
However as you're inside a for loop, you could run into an ArrayIndexOutOfBoundsException, so, a better idea would be:
for(int i=1; i<Array.length;i++) { //Look the "i" was initialized with 1 and not with 0.
REMEMBER: ARRAYS START FROM 0 INDEX
If you want to "skip" the first element, then the above modification to for loop should work, but if you want it to run from 1 to 10 then it's a bad idea, because it should be from 0 to 9
You should also be careful to follow the Java naming conventions:
firstWordLowerCaseVariable
firstWordLowerCaseMethod()
FirstWordUpperCaseClass
ALL_WORDS_UPPER_CASE_CONSTANT
and use them consistently, this will make your code easier to read and understand for you and for us.
Also, try not to name your classes / variables as Java classes names:
Object or Array or List, etc might be wrong choices, also having object lowercase would be a bad idea as it's not descriptive either as suggested by #nicomp on the comments below
but when i type Array [i + 1] it still prints out from index 0, if for example i where to make i dice i would want it to start at index 1, is there no way to do this?
I think you didn't changed the for(int j=0;j<Array.length;j++) { loop, to start from 1
To make a dice I would:
Create the array with 6 slots (starting from 0)
Fill it (1 - 6) like below (inside a for loop):
dice[0] = 1;
dice[1] = 2;
...
dice[5] = 6;
//Example of for loop
for (int i = 0; i < dice.length; i++) {
dice[i] = i + 1;
}
Get a random number (between 0 - 5) called random
Get the value of the array at position random
For example:
random = 3;
//dice[random] = 4;
System.out.println(dice[random]);

Taking data from one array to create another. What's wrong with this loop?

I am working on an assignment where I need to create two arrays, then look through them and create a new array that holds any values inside of both the first two. Originally, I was close to accomplishing this by making an arraylist but my lab professor told me that wasn't allowed so I needed to re-start and didn't have enough time to figure out the solution.
If you'd like to see the whole code I have now: http://pastebin.com/thsYnj2z
I am really struggling with this loop here:
for(int i = 0 ; i < Xarr.length ; i++){
for(int j = 0 ; j < Yarr.length ; j++)
//Compare. If the two are the same, they go inside of A.
if (Xarr[i] == Yarr[j]){
ArrA[k] = Xarr[i];
k++;
System.out.println(ArrA[k]);
break;
}
My output is remaining 0 for my ArrA[k] array. I can't seem to trouble shoot this issue on my own.
try making these changes
for(int i = 0 ; i < Xarr.length ; i++){
for(int j = 0 ; j < Yarr.length ; j++)
//Compare. If the two are the same, they go inside of A.
if (Xarr[i] == Yarr[j]){
ArrA[k] = Xarr[i];
System.out.println(ArrA[k]); // or print them all later
k++;
break; // break to outer loop
}
}
}
note
Assuming OP has correctly initialized ArrA
note2
Assuming that only unique values are required, hence the breaking
Does your solution require that no values are duplicated in ArrA? Or are duplicate values allowed? For example, if some values occur multiple times in each array, you could get multiple matches on the same number.
If duplicates aren't a problem:
for(int i = 0 ; i < Xarr.length ; i++){
for(int j = 0 ; j < Yarr.length ; j++){
//Compare. If the two are the same, they go inside of A.
if (Xarr[i] == Yarr[j]){
ArrA[k] = Xarr[i];
System.out.println(ArrA[k]);
k++;
}
}}
As I understand it, the problem is to take 2 arrays, and produce a third array which is a Union of the first 2. Union of 2 sets being the subset of the values found in both sets.
Your code was missing some braces, so put those back in there. Also you wont want to print the k+1th item after you just put a value in ArrA[k] im assuming.
Otherwise you were pretty much there. The break terminates the inner loop and allows the outer loop to increment i and continue on. This is because you have already found a match, no need to continue searching, just move onto the next index in Xarr.
Algorithm goes like this: For each value in X, search Y for a match. If it is found, add this value to A.
for(int i = 0 ; i < Xarr.length ; i++) {
for(int j = 0 ; j < Yarr.length ; j++) {
//Compare. If the two are the same, they go inside of A.
if (Xarr[i] == Yarr[j]){
ArrA[k] = Xarr[i];
System.out.println(ArrA[k]);
k++; //you probably want to increment k after you add to ArrA, not before
break;
}
}
}
public static void main(String... args){
int[] xArr = {1, 1,1,1,1,1};
int[] yArr = {1, };
int[] kArr = new int[xArr.length > yArr.length ? xArr.length : yArr.length];
int k = 0;
for(int x = 0; x < xArr.length; x++){
for(int y = 0; y < yArr.length; y ++){
int xNum = xArr[x];
int yNum = yArr[y];
if(xNum == yNum) kArr[k++] = xNum;
}
}
int[] resizedKArr = new int[k];
for(int i = 0; i < resizedKArr.length; i++) resizedKArr[i] = kArr[i];
Arrays.sort(resizedKArr);
for(int x : resizedKArr) System.out.println(x);
}
First, xArr and yArr are given some random numbers, and then kArr is initialized with the size of the lagest array we are comparing with to ensure the array has enough space to hold similar values.
Then, in the next section we do a loop inside of a loop to compare the values against each other and if they are similar then k++ and set the next value in the array. This goes on until the loops are completed, notice there really is never a need to break from either loop until all values are compared. At that point the loops break themselves and move on to the next bit of code.
The last section is just to create an array of the same size as k and move the values over, I don't know the requirements of your studies, although when using primitives like this you may want to do this in case you have a matching 0 as a number. Otherwise you'll have a ton of 0s filling the empty spaces of your array.
And lastly, we just sort the array for good measure and print it out.
Hope I've answered your question and you get something out of this post!
The problem is printing ArrA[k] after k++. Try increasing line after print.

Averaging array values not coming out as expected, gives out of place value instead of correct one

I'm writing a program for a class at school, and when the independents couldn't help, I turn to you...
I encounter my issue when I attempt to find the average - the variables either don't add correctly or they don't divide correctly. For example, an input of [4], [2], [4], [2], will give me 7.0, when it should be 3.0. Similarly, [2], [2], [4], [4], will give 2.0.
As far as I'm aware, the rest of the code functions exactly as it should. I'm including only what should effect it, but I can post the rest if required.
public class ArrayFunctions
{
String elementNumber =
JOptionPane.showInputDialog("How many elements do you want?");
int number = Integer.parseInt(elementNumber);
//assigns how many elements are in the array, based on user input
int[] min_array = new int[number];
int recalculate = 0;
public void arrayValues()
{
for (int i = 1; i < (number + 1); i++)
{
String elementInfo =
JOptionPane.showInputDialog("Input value for element " + i);
int element = Integer.parseInt(elementInfo);
//assigns values for elements, based on user input
min_array[(i - 1)] = element;
}
System.out.println('\u000C'); /*using BlueJ, this clears the console*/
for (int i = 1; i < (number + 1); i++)
{
System.out.println(min_array[(i - 1)]);
}
//prints the values of the elements in the array
}
...
public double avg()
{
for (int i = 1; i < (min_array.length); i++)
{
recalculate = (recalculate + min_array[(i - 1)]);
}
//should add together the values of all the elements
//this may be where it stops working as intended
double array_avg = (recalculate / min_array.length);
return array_avg;
//should divide the sum of all the elements by how many elements there are
//this is the other place where it might stop working.
}
Again, I can post more code if required. Sorry about bad/lacking comments and poor structure at times, I need to get this written, because I've a due date for this. :/
for (int i = 1; i < (min_array.length); i++)
{
recalculate = (recalculate + min_array[(i - 1)]);
}
This loop is going between index 0 (1 - 1) and index min_array.length - 2 due to your boolean condition in the for loop, stating that it should go while i is LESS than the array's length, and then also subtracting it by 1 in the code.
A possible solution would be to simply go until it's less than OR equal to the size, or simply start your loop at 0 and stop the (i - 1) stuff in the average calculation.
for (int i = 0; i < min_array.length; i++)
{
recalculate += min_array[i];
}
Also, on a side note, you're basically making that same mistake in the GUI stuff as well above; I've corrected it (as well as kept your methodology of using 1-based indexing for asking the user to fill in values, rather than 0-based indexing)
for (int i = 0; i < number; i++){
String elementInfo =
JOptionPane.showInputDialog("Input value for element " + (i + 1));
int element = Integer.parseInt(elementInfo);
min_array[i] = element;
}
System.out.println('\u000C'); /*using BlueJ, this clears the console*/
for (int i = 0; i < number; i++){
System.out.println(min_array[i]);
}
I see that you're going from index 0 to index array.length - 2, instead of -1. That's the problem. I hope this helps
public double avg()
{
for (int i = 0; i < (min_array.length); i++)
{
recalculate = (recalculate + min_array[i]);
}
//should add together the values of all the elements
//this may be where it stops working as intended
double array_avg = (recalculate / min_array.length);
return array_avg;
//should divide the sum of all the elements by how many elements there are
//this is the other place where it might stop working.
}
Also always start a for loop with i=0 for counting purposes

Reverse printing of an array

(Java beginner)
I came up with a code that would display an int array in reverse and although I know there's probably a better way to do it, I think this logic should work:
for(int i = 0, j = numList.length - 1; i < j; i++, j--)
{
int temp = numList[i];
numList[i] = numList[j];
numList[j] = temp;
System.out.print("Reverse order: " + temp + " ");
}
What I don't understand is that when I enter 5 numbers, the console only shows the first two numbers and it ends there:
1
2
3
4
5
Reverse order: 1 2
What's wrong here and what can I do to fix it?
That code is just faulty. Use this instead.
for(int i = numList.Length - 1; i >= 0;i--)
{
int temp = numList[i];
System.out.print("Reverse order: " + temp + " ");
}
In your code, you increment i and decrement j, meaning that if you'd loop untill your condition is satisfied, you'd get about half the loop done. Try and create a table of the values of your loop step by step, you'll see what I mean :)
i++ and j-- along with the loop iteration condition of i < j would become false when i and j reach the middle of the array. So essentially your for loop is only working up the first half of the loop. I didnt run you code but this is the first observation i made.

Round robin scheduler using a linked list

I'm trying to write a very simple OS simulator and I am stuck getting my round robin algorithm to work. Basically what i am trying to do is create a circular linked list that stores the burst values of the process. Right now I am getting a null pointer exception. It has been awhile since I've used a linked list so bear with my code:
public static void RR3(int numProcess, int[] cpuBurst, int[] arrivalTime){
int quantum = 3,time = 0, temp;
int completionTime = 0;
LinkedList <Integer>process = new LinkedList();
for (int i = 0; i < numProcess; i++) {
process.add(i, cpuBurst[i]);
}
while (process.isEmpty() != true){
for (int j = 0; j < quantum; j++) {
System.out.println(process.getFirst());
if(process.peek() == 0 ){
completionTime = completionTime + time;
process.remove();
}
else{
temp = process.pop();
process.push(temp - 1);
time++;
}
}
process.addLast(process.getFirst());
process.removeFirst();
}
double act = (double) completionTime/numProcess;
System.out.println("-----------------RR3-----------------");
System.out.println(" Act = " + act + "ms");
}
Am I using linked list right? Any help is appreciated.
edit:
I put in System.out.println(process.getFirst()); after the first for loop to get some sort of stack trace and this is my output:
6
5
4
4
3
2
10
9
8
7
6
5
3
2
1
7
6
5
Exception in thread "main" java.util.NoSuchElementException
4
3
2
1
4
3
1
at java.util.LinkedList.getFirst(LinkedList.java:242)
2
1
at OsSimulator.RR3(OsSimulator.java:61)
at OsSimulator.main(OsSimulator.java:79)
Java Result: 1
my burst time i entered were 6,4,10,7 so it looks like it is on the right track but i get the error with this line
process.addLast(process.getFirst());
and now its a no such element exception.
I don't have access to eclipse to check this at the moment, but are you sure you aren't trying to call process.getFirst() after the last element is removed from the list inside of the for loop?
I would suggest putting a breakpoint before that line and then running the code in debug mode to verify.
It means what it says. There is no first element, so the process list is empty.
This must be occurring because processing the quanta in the j loop has made the list empty.
If you add trace code to print out the whole list during each iteration rather than just the first element, it will become pretty obvious what's happening.
Debugging is always about making yourself see what is really going on instead of guessing at an opaque puzzle. The main tool you have to visualize what's really going on (when your brain fails you) is the machine itself. Add trace code or become expert with a debugger. The discipline is to force yourself to see truth.
Before calling process.getFirst() make sure List is not empty
public static void RR3(int numProcess, int[] cpuBurst, int[] arrivalTime) {
int quantum = 3, time = 0, temp;
int completionTime = 0;
LinkedList<Integer> process = new LinkedList<Integer>();
for (int i = 0; i < numProcess; i++) {
process.add(i, cpuBurst[i]);
}
while (process.isEmpty() != true) {
for (int j = 0; j < quantum; j++) {
if (process.size() == 0)
break;
System.out.println("Process: " + process.getFirst());
if (process.peek() == 0) {
completionTime = completionTime + time;
process.remove();
} else {
temp = process.pop();
process.push(temp - 1);
time++;
}
}
if (process.size() == 0)
break;
process.addLast(process.getFirst());
process.removeFirst();
}
double act = (double) completionTime / numProcess;
System.out.println("-----------------RR3-----------------");
System.out.println(" Act = " + act + "ms");
}

Categories