Comparing adjacement array elements - java

I'm trying to work out the difference in adjacent pairs of array elements, and then add the differences together, this is the method I'm using to do this.
I'm trying to split the original array into two smaller arrays and then subtract elements of the smaller arrays which will indirectly workout the difference of my initial array. the diffrences get stored on a last array which adds my differences together....
public static int changeinx(int array1[],int sum) {
int n = array1.length;
int y[];
int u[];
int c[];
c = new int [n/2];
y = new int [n/2]; // no. of arrays equal to 1/2 of array1, since two elements subtracted.
u = new int [n/2];
for(int i = 0 ; i < n ; i += 2 ) {
y[i] = array1[i];
}
for(int i = 1 ; i < n ; i += 2) {
u[i] = array1[i];
}
for(int i = 0 ; i < n/2 ; i++ ) {
c[i] = Math.abs( u[i] - y[i] ) ;
}
for(int r = 0 ; r < c.length ; r++ ) {
sum = sum + c[r]; //adding all the differences up, since abs has been taken
}
return sum ;
}
Why is this not working? :(

I find a major flaw in this loop:
for(int i = 0 ; i < n ; i++) {
int x = array1[i] - array1[i+1] ;
Let me give an example to illustrate this further, say we have an array
array1 = 25 15 55 12
the above loop at first iteration would do 25-15
in the 2nd iteration do 15-55
and 3rd iteration do 55-12
So now running this loop on an array of 4 elements would yield an array with 3 elements not at all conforming to your n/2 formula.
From my understanding of your problem I think your intention is to do 25-15 in the first loop
55-12 in the 2nd loop and end it, as to how you would go about doing it I leave it to you to figure out

This loop never ends:
for(int p = 0 ; p < n ; i++ ) {
y[p] = Math.abs(x); //trying to the difference as x, and asign to array y[]
}
Since p and n never change during the loop, if p < n is not true when the loop starts, it will never be true, and the loop will never end.
I'm trying to work out the difference in adjacent pairs of array elements, and then add the differences together, this is the method I'm using to do this.
If I understood the problem description correctly, this can be implemented much simpler:
public static int changeinx(int[] arr) {
int sumOfDiffs = 0;
for (int i = 0; i < arr.length - 1; i++) {
sumOfDiffs += Math.abs(arr[i] - arr[i + 1]);
}
return sumOfDiffs;
}

Related

Creating a method that merges 2 arrays into one sorted array in ascending order in Java

For part of an assignment, I have to create a method that merges 2 arrays into one sorted array in ascending order. I have most of it done, but I am getting a bug that replaces the last element in the array with 0. Has anyone ever run into this problem and know a solution? Heres my code:
public static OrderedArray merge(OrderedArray src1, OrderedArray src2) {
int numLength1 = src1.array.length;
int numLength2 = src2.array.length;
//combined array lengths
int myLength = (numLength1 + numLength2);
// System.out.println(myLength);
OrderedArray mergedArr = new OrderedArray(myLength);
//new array
long[] merged = new long[myLength];
//loop to sort array
int i = 0;
int j = 0;
int k = 0;
while (k < src1.array.length + src2.array.length - 1) {
if(src1.array[i] < src2.array[j]) {
merged[k] = src1.array[i];
i++;
}
else {
merged[k] = src2.array[j];
j++;
}
k++;
}
//loop to print result
for(int x = 0; x < myLength; x++) {
System.out.println(merged[x]);
}
return mergedArr;
}
public static void main(String[] args) {
int maxSize = 100; // array size
// OrderedArray arr; // reference to array
OrderedArray src1 = new OrderedArray(4);
OrderedArray src2 = new OrderedArray(5);
// arr = new OrderedArray(maxSize); // create the array
src1.insert(1); //insert src1
src1.insert(17);
src1.insert(42);
src1.insert(55);
src2.insert(8); //insert src2
src2.insert(13);
src2.insert(21);
src2.insert(32);
src2.insert(69);
OrderedArray myArray = merge(src1, src2);
This is my expected output:
1
8
13
17
21
32
42
55
69
and this is my current output:
1
8
13
17
21
32
42
55
0
While merging two arrays you are comparing them, sorting and merging but what if the length of two arrays is different like Array1{1,3,8} and Array2{4,5,9,10,11}. Here we will compare both arrays and move the pointer ahead, but when the pointer comes at 8 in array1 and at 9 in array2, now we cannot compare ahead, so we will add the remaining sorted array;
Solution:-
(Add this code between loop to sort array and loop to print array)
while (i < numLength1) {
merged[k] = src1.array[i];
i++;
k++;
}
while (j < numLength2) {
merged[k] = src2.array[j];
j++;
k++;
}
To answer your main question, the length of your target array is src1.array.length + src2.array.length, so your loop condition should be one of:
while (k < src1.array.length + src2.array.length) {
while (k <= src1.array.length + src2.array.length - 1) {
Otherwise, you will never set a value for the last element, where k == src1.array.length + src2.array.length - 1.
But depending on how comprehensively you test the code, you may then find you have a bigger problem: ArrayIndexOutOfBoundsException. Before trying to use any array index, such as src1.array[i], you need to be sure it is valid. This condition:
if(src1.array[i] < src2.array[j]) {
does not verify that i is a valid index of src1.array or that j is a valid index of src2.array. When one array has been fully consumed, checking this condition will cause your program to fail. You can see this with input arrays like { 1, 2 } & { 1 }.
This revision of the code does the proper bounds checks:
if (i >= src1.array.length) {
// src1 is fully consumed
merged[k] = src2.array[j];
j++;
} else if (j >= src2.array.length || src1.array[i] < src2.array[j]) {
// src2 is fully consumed OR src1's next is less than src2's next
merged[k] = src1.array[i];
i++;
} else {
merged[k] = src2.array[j];
j++;
}
Note that we do not need to check j in the first condition because i >= src1.array.length implies that j is a safe value, due to your loop's condition and the math of how you are incrementing those variables:
k == i + j due to parity between k's incrementing and i & j's mutually exclusive incrementing
k < src1.array.length + src2.array.length due to the loop condition
Therefore i + j < src1.array.length + src2.array.length
If both i >= src1.array.length and j >= src2.array.length then i + j >= src1.array.length + src2.array.length, violating the facts above.
A couple other points and things to think about:
Be consistent with how you refer to data. If you have variables, use them. Either use numLength1 & numLength2 or use src1.length & src2.length. Either use myLength or use src1.array.length + src2.array.length.
Should a merge method really output its own results, or should the code that called the method (main) handle all the input & output?
Is the OrderedArray class safe to trust as "ordered", and is it doing its job properly, if you can directly access its internal data like src1.array and make modifications to the array?
The best way to merge two arrays without repetitive items in sorted order is that insert both of them into treeSet just like the following:
public static int[] merge(int[] src1, int[] src2) {
TreeSet<Integer> mergedArray= new TreeSet<>();
for (int i = 0; i < src1.length; i++) {
mergedArray.add(src1[i]);
}
for (int i = 0; i < src2.length; i++) {
mergedArray.add(src2[i]);
}
return mergedArray.stream().mapToInt(e->(int)e).toArray();
}
public static void main(String[] argh) {
int[] src1 = {1,17,42,55};
int[] src2 = {8,13,21,32,69};
Arrays.stream(merge(src1,src2)).forEach(s-> System.out.println(s));
}
output:
1
8
13
17
21
32
42
55
69

Creating a changing sequence of numbers in a for loop Java?

I'm trying to increment the following sequence in a for loop (Java):
1, 4, 9, 16, 25 etc the difference increasing by two each time. I tried using 'i+=3 + i' but I know that's wrong since it doesn't take into account that the variable i changes along the sequence.
Any help? Thanks
You could have an increment of i+=k and change k inside the loop in order to change the increment.
int k=1;
for (int i=1;i<1000;i+=k) {
k+=2;
}
If your i is changing, the simple logic is, use another variable that is declared outside the scope of the loop. This will make sure that it is not recreated everytime the loop runs.
int num = 1;
for(int i=1; i<maxValue; num+=2,i+=num){
//Use the value of `i` here, it will be as you wanted.
}
The sequence is to start with j=1 and k=4 and then derive next values of the series n times. The formula as follow:
Initial loop (i=0):
j = 1, k = 4;
Loop (i > 0 less than n):
Repeat below n times:
temp = k;
k = k + (k - j + 2);
j = temp;
print value of j being the series;
I assume that you take n as input from user and then generate the series nth times. Let's look at the following code example
int n = 10;
for(int i = 0, temp = 0, j = 1, k = 4; i < n; i++, temp = k, k += (k-j+2), j = temp) {
System.out.println(j);
}
Assuming that user inputs n = 10, the loop initializes i = 0 and continues until i < n is satisfied. It initializes j = 1 and k = 4 and then execute the body of the loop (printing j) followed by backing up the value of k, calculating new value for k and replacing the old value of j. The output for n = 10 is as follow:
1
4
9
16
25
36
49
64
81
100
Read Series number from the user and generate series based on given number.
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int ans;
for(int i = 1; i <= n; i++){
ans = i * i;
System.out.println(ans);
}

2D array in java gives java.lang.ArrayIndexOutOfBoundsException

I am new to Java and i am using eclipse for its compilation. I have seen many forums but i am not able to get around this error. I am creating a program for my homework and this is a small section of that program which is giving weird error. Any help is appreciated.
Here is where i am getting error -> aTwoD[i][j] = 0; <- at Initialize2D.<init>(Initialize2D.java:19)
I am stuck on this for quite some time now.
:-(
What is did ->
public class Initialize2D
{
private int[][] aTwoD;
public Initialize2D (int N)
{
System.out.println("N = " +N);
int counter = 0;
aTwoD = new int[N][N];
int i = 1;
while( i <= N )
{
int j = 1;
while( j <= N )
{
System.out.println("counter = " +counter);
aTwoD[i][j] = 0;
System.out.println("aTwoD["+i+"]["+j+"] = " + aTwoD[i][j]);
j++;
counter++;
}
i++;
}
}
public static void main( String[] args)
{
Initialize2D TwoDArray = new Initialize2D(2);
}
}
index starts from 0 so <= would cause out of bound
Array indices in Java start at 0, and end at length - 1. They don't start at 1 and end at length as your code assumes.
change
while( j <= N )
to
while( j < N )
In java indexing of N size array goes from 0 to N-1 including.
Beware that you iterate over i and j with the condition i <= N, j <= N.
Arrays in Java are zero based, meaning that they range between: 0 ... N-1.
If you access them with N that will be out of their range.
Change your iterator from i <= N to i < N (same for j). That should do the trick.

Going back to the first index after reaching the last one in an array

After my array in the for loop reaches the last index, I get an exception saying that the index is out of bounds. What I wanted is for it to go back to the first index until z is equal to ctr. How can I do that?
My code:
char res;
int ctr = 10
char[] flames = {'F','L','A','M','E','S'};
for(int z = 0; z < ctr-1; z++){
res = (flames[z]);
jLabel1.setText(String.valueOf(res));
}
You need to use an index that is limited to the size of the array. More precisely, and esoterically speaking, you need to map the for-loop iterations {0..9} to the valid indexes for the flame array {0..flames.length()-1}, which are the same, in this case, to {0..5}.
When the loop iterates from 0 to 5, the mapping is trivial. When the loop iterates a 6th time, then you need to map it back to array index 0, when it iterates to the 7th time, you map it to array index 1, and so on.
== Naïve Way ==
for(int z = 0, j = 0; z < ctr-1; z++, j++)
{
if ( j >= flames.length() )
{
j = 0; // reset back to the beginning
}
res = (flames[j]);
jLabel1.setText(String.valueOf(res));
}
== A More Appropriate Way ==
Then you can refine this by realizing flames.length() is an invariant, which you move out of a for-loop.
final int n = flames.length();
for(int z = 0, j = 0; z < ctr-1; z++, j++)
{
if ( j >= n )
{
j = 0; // reset back to the beginning
}
res = (flames[j]);
jLabel1.setText(String.valueOf(res));
}
== How To Do It ==
Now, if you are paying attention, you can see we are simply doing modular arithmetic on the index. So, if we use the modular (%) operator, we can simplify your code:
final int n = flames.length();
for(int z = 0; z < ctr-1; z++)
{
res = (flames[z % n]);
jLabel1.setText(String.valueOf(res));
}
When working with problems like this, think about function mappings, from a Domain (in this case, for loop iterations) to a Range (valid array indices).
More importantly, work it out on paper before you even begin to code. That will take you a long way towards solving these type of elemental problems.
While luis.espinal answer, performance-wise, is better I think you should also take a look into Iterator's as they will give you greater flexibility reading back-and-forth.
Meaning that you could just as easy write FLAMESFLAMES as FLAMESSEMALF, etc...
int ctr = 10;
List<Character> flames = Arrays.asList('F','L','A','M','E','S');
Iterator it = flames.iterator();
for(int z=0; z<ctr-1; z++) {
if(!it.hasNext()) // if you are at the end of the list reset iterator
it = flames.iterator();
System.out.println(it.next().toString()); // use the element
}
Out of curiosity doing this loop 1M times (avg result from 100 samples) takes:
using modulo: 51ms
using iterators: 95ms
using guava cycle iterators: 453ms
Edit:
Cycle iterators, as lbalazscs nicely put it, are even more elegant. They come at a price, and Guava implementation is 4 times slower. You could roll your own implementation, tough.
// guava example of cycle iterators
Iterator<Character> iterator = Iterators.cycle(flames);
for (int z = 0; z < ctr - 1; z++) {
res = iterator.next();
}
You should use % to force the index stay within flames.length so that they make valid index
int len = flames.length;
for(int z = 0; z < ctr-1; z++){
res = (flames[z % len]);
jLabel1.setText(String.valueOf(res));
}
You can try the following:-
char res;
int ctr = 10
char[] flames = {'F','L','A','M','E','S'};
int n = flames.length();
for(int z = 0; z < ctr-1; z++){
res = flames[z %n];
jLabel1.setText(String.valueOf(res));
}
Here is how I would do this:
String flames = "FLAMES";
int ctr = 10;
textLoop(flames.toCharArray(), jLabel1, ctr);
The textLoop method:
void textLoop(Iterable<Character> text, JLabel jLabel, int count){
int idx = 0;
while(true)
for(char ch: text){
jLabel.setText(String.valueOf(ch));
if(++idx < count) return;
}
}
EDIT: found a bug in the code (idx needed to be initialized outside the loop). It's fixed now. I've also refactored it into a seperate function.

two dimensional array sorting using all elements

I'm working on this code in my program right now and it seems that the problem is with the line where I stop the inner loop of the 2nd dimension.
this is a sample output of the array
9 6 6
7 6 4
4 8 5
when i run this code the output is:
4 4 6
5 6 6
7 8 9
my expected output is:
4 4 5
6 6 6
7 8 9
a digit:"6" is not in the correct place. Its because when I try to run the part where there is a nested for loop above a for loop, it only runs once and so it only checks the 1st column instead of getting to the third column where 6 is. The problem is I need to limit that loop in only reading the highest numbers from row#0 column#0 to row#2 column#0.
How do I solve this problem?? I thought of using a one dimensional array and put all two dimensional array elements and sort it there then put it back to the two dimensional array and print it again but that wouldn't make my code solve the needed process of sorting two dimensional array.
public static void sortArray(){
int x = len-1, y = len-1;
int iKey=0,jKey=0;
int cnt=0;
do{
cnt++;
if(y==-1){
x--;
y=len-1;
}
System.out.println(cnt+".)"+x+"-"+y);
int hi = -1;
for(i = 0;i <= x; i++)
for(j = 0;j <= y; j++){
if(twodiArray[i][j]>hi){
hi = twodiArray[i][j];
iKey = i;
jKey = j;
}
}
int temp = twodiArray[iKey][jKey];
twodiArray[iKey][jKey] = twodiArray[x][y];
twodiArray[x][y] = temp;
//dispArray();
y--;
}while(cnt<9);
}
The problem is in your loops where you search max element. Suppose you have array 5x5 and x=1 and y=1. Then you loop will check only following elements: [0][0], [0][1], [1][0], [1][1]. But it should also check [0][2], [0][3], [0][4].
With you previous code you only checked following cells:
XX...
XX...
.....
.....
.....
But you need to check these:
XXXXX
XX...
.....
.....
.....
So you need something like this:
for(i = 0;i <= x; i++) {
int upper; // How many elements we need to check on current row.
if (i != x) {
upper = len - 1; // We are not in last row, so check all elements.
} else {
upper = y; // On the last row we need to check only elements up to y.
}
for(j = 0;j <= upper; j++){
if(twodiArray[i][j]>hi){
hi = twodiArray[i][j];
iKey = i;
jKey = j;
}
}
}
My code checks every row fully until last one.
EDIT
If you use:
for (int i = 0; i <= x; i++) {
for (int j = 0; j <= y; j++) {
...
}
}
then you iterate only on recangle with upper left corner in (0,0) and right bottom cornar in (y,x). E.g. x = 4, y = 3:
XXX...
XXX...
XXX...
XXX...
......
But your goal is to do every row before last one fully. So check 0-th, 1-st and 2-nd rows fully and 3 elements from 3-rd row. My code does it. upper show how many values from row we need to check for all rows except last one it's equals to len - 1 (check full row). For last one it's y.
Your swap code (starting with int temp = twodiArray) is outside the main iteration loop. It needs to be moved inside the innermost loop.
BTW, you can do the swap without storing the indices.
Personally, to save myself some confusion, I would think of it as if it were a 1D array.
// I'm assuming that columnCount and rowCount are stored somewhere
public int getNthElement(int index) {
int colIndex = index % columnCount;
int rowIndex = (index - colIndex) / rowCount;
return twodiArray[rowIndex][colIndex];
}
public void setNthElement(int index, int value) {
int colIndex = index % columnCount;
int rowIndex = (index - colIndex) / rowCount;
twodiArray[rowIndex][colIndex] = value;
}
public void sortArray(int[][] array) {
int elementCount = rowCount * columnCount;
int curIndex = elementCount - 1;
while (curIndex >= 0) {
int highestIndex = -1;
int highestValue = 0;
for (int i = 0; i <= curIndex; i++) {
int nthValue = getNthElement(i);
if (nthValue > highestValue) {
highestIndex = i;
highestValue = nthValue;
}
}
int swapValue = getNthElement(curIndex);
setNthElement(curIndex, highestValue);
setNthElement(highestIndex, swapValue);
curIndex--;
}
}
You can see that I still use the 2D array and never use an actual 1D array, but this code indexes into the array as if it were a 1D array. (Hopefully that is valid in your professor's eyes)

Categories