Unable to reverse integers in an array, fails halfway thru - java

I want to reverse the integers in Array 's'. I can't figure out why the output is reversing on itself. Link for code
http://ideone.com/REuGYt
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
int[] s = {4,5,6,7,8};
for (int x = 0; x < s.length; x++) {
s[x] = s[(s.length - x) -1];
System.out.println(s[x]);
}
}
}
//outputs
8
7
6
7
8

You are only copying the right side values to the left side values; you aren't switching the values from both sides. Instead of just copying the right side to the left side, swap their values. Replace
s[x] = s[(s.length - x) -1];
with
int temp = s[x];
s[x] = s[(s.length - x) -1];
s[(s.length - x) -1] = temp;
Additionally, you will need to stop your for loop halfway through the array, before x reaches s.length/2, or else the second half will swap the values back to their original locations.

Try this:
List<Integer> reversed = Arrays.asList(4,5,6,7,8);
Collections.reverse(reversed);
It'll build a collection, then reverse it.

You're changing the values in the array as you iterate. When you get halfway through your array you begin to print out values that you previously wrote in. This makes it appear mirrored. One fix is by using two arrays:
int[] s = {4, 5, 6, 7, 8};
int[] rev = new int[s.length];
for (int x = 0; x < s.length; x++) {
rev[x] = s[(s.length - x) - 1];
System.out.println(rev[x]);
}

Related

Trying to create a array with the intersection of two arrays but fails at creating array with the proper structure

So, I am trying to create 2 randomly generated arrays,(a, and b, each with 10 unique whole numbers from 0 to 20), and then creating 2 arrays with the info of the last two. One containing the numbers that appear in both a and b, and another with the numbers that are unique to a and to b. The arrays must be listed in a "a -> [1, 2, 3,...]" format. At the moment I only know how to generate the 2 arrays, and am currently at the Intersection part. The problem is, that I can create a array with the correct list of numbers, but it will have the same length of the other two, and the spaces where it shouldn't have anything, it will be filled with 0s when its supposed to create a smaller array with only the right numbers.
package tps.tp1.pack2Arrays;
public class P02ArraysExtractUniqsAndReps {
public static void main(String[] args) {
int nbr = 10;
int min = 0;
int max = 20;
generateArray(nbr, min, max);
System.out.println();
}
public static int[] generateArray(int nbr, int min, int max) {
int[] a = new int[nbr];
int[] b = new int[nbr];
int[] s = new int[nbr];
s[0] = 0;
for (int i = 0; i < a.length; i++) {
a[i] = (int) (Math.random() * (max - min));
b[i] = (int) (Math.random() * (max - min));
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
i--;
}
if (b[i] == b[j]) {
i--;
}
}
}
System.out.println("a - > " + Arrays.toString(a));
System.out.println("b - > " + Arrays.toString(b));
for (int k = 0; k < a.length; k++) {
for (int l = 0; l < b.length; l++) {
if (a[k] == b[l]) {
s[l] = b[l];
}else {
}
}
}
System.out.println("(a ∪ (b/(a ∩ b)) - > " + Arrays.toString(s));
return null;
}
public static boolean hasValue(int[] array, int value) {
for (int i = 0; i < array.length; i++) {
if (array[i] == value) {
return true;
}
}
return false;
}
}
Is there any way to create the array without the incorrect 0s? (I say incorrect because it is possible to have 0 in both a and b).
Any help/clarification is appreciated.
First, allocate an array large enough to hold the intersection. It needs to be no bigger that the smaller of the source arrays.
When you add a value to the intersection array, always add it starting at the beginning of the array. Use a counter to update the next position. This also allows the value 0 to be a valid value.
Then when finished. use Array.copyOf() to copy only the first part of the array to itself, thus removing the empty (unfilled 0 value) spaces. This works as follow assuming count is the index you have been using to add to the array: Assume count = 3
int[] inter = {1,2,3,0,0,0,0};
inter = Arrays.copyOf(inter, count);
System.out.println(Arrays.toString(inter);
prints
[1,2,3]
Here is an approach using a List
int[] b = {4,3,1,2,5,0,2};
int [] a = {3,5,2,3,7,8,2,0,9,10};
Add one of the arrays to the list.
List<Integer> list = new ArrayList<>();
for(int i : a) {
list.add(i);
}
Allocate the intersection array with count used as the next location. It doesn't matter which array's length you use.
int count = 0;
int [] intersection = new int[a.length];
Now simply iterate thru the other array.
if the list contains the value, add it to the intersection array.
then remove it from the list and increment count. NOTE - The removed value must be converted to an Integer object, otherwise, if a simple int value, it would be interpreted as an index and the value at that index would be removed and not the actual value itself (or an Exception might be thrown).
once finished the intersection array will have the values and probably unseen zeroes at the end.
for(int i = 0; i < b.length; i++) {
int val = b[i];
if (list.contains(val)) {
intersection[count++] = val;
list.remove(Integer.valueOf(val));
}
}
To shorten the array, use the copy method mentioned above.
intersection = Arrays.copyOf(intersection, count);
System.out.println(Arrays.toString(intersection));
prints
[3, 2, 5, 0, 2]
Note that it does not matter which array is which. If you reverse the arrays for a and b above, the same intersection will result, albeit in a different order.
The first thing I notice is that you are declaring your intersection array at the top of the method.
int[] s = new int[nbr];
You are declaring the same amount of space for the array regardless of the amount you actually use.
Method Arrays.toString(int []) will print any uninitialized slots in the array as "0"
There are several different approaches you can take here:
You can delay initializing the array until you have determined the size of the set you are dealing with.
You can transfer your content into another well sized array after figuring out your result set.
You could forego using Array.toString, and build the string up yourself.

Creating a program that increments Arrays

An integer array stores values 3,2,3,4,5. I am trying to create a program that increments these values by 2 and then saves the result into the same array using a for loop. I tried but something is wrong with my code, here:
public class ArrayClass {
int a[] = {2, 3, 3, 4, 5};
}
public class ArrayObject {
public static void main(String[] Ella) {
int a[] = new int[5];
int i;
for (i = 2; i < a.length; i = i + 2) {
a[i] = i + 2;
System.out.println(a[i]);
}
}
}
This should work:
for (i = 0; i < a.length; i++) {
a[i] += 2;
System.out.println(a[i]);
}
You see, when increasing every single value of an array, the index has to be 0 and max the array's length. By adding one to i, the indexing of the array increases by one, which means the next number will be increased by two. what you did was add two to the "i" variable which means that only 3 of the varialbes would have been changed.
Please make below change to your code.It will work.
for (i = 0; i < a.length; i++) {
a[i] = a[i] + 2;
System.out.println(a[i]);
}
The error is that when you do i = i + 2, you are just incrementing the position index, not the actual value in that position.
you need to do:
a[i] = a[i]+2;
Let me explain what a[i] is:
|3|2|3|4|5|
1 2 3 4 5
The first row are the values. The second row is the index. "Index" means the position number of each of positions in the array.
Another problem is that, when you initialise i, it need to be i=0. That is because i array indices (plural of index) always start from 0. That means that a[0] is the first position in the array That would be number 3 from your data set.

sort an array, so that first and last element will form a "pair"

I have an array of objects which I want to sort by indices in the following order. I will always have an array size to the power of 2.
Example array size: 8. Indices: [0][1] [2][3] [4][5] [6][7]
After sort: [0][7] [1][6] [2][5] [3][4]
So basically alternating between first and last element which was not sorted yet.
I already thought of a way of doing it, and I can get the "pairs" but they are in the wrong order (and I think it would not work with any other to the power of 2 array?).
Here I'm using an int array and their indices as values to make it simpler for myself.
int[] array = new int[]{0,1,2,3,4,5,6,7};
int[] sortedArray = new int[8];
for(int i = 0; i < array.length; i+=2){
sortedArray[i] = array[i];
}
for(int i = 1; i < array.length; i+=2){
sortedArray[i] = array[array.length - i];
}
Output: [0][7] [2][5] [4][3] [6][1]
You can do this with a single loop. Consider the following algorithm:
int[] array = new int[]{0,1,2,3,4,5,6,7};
int[] sortedArray = new int[8];
for(int i = 0; i < array.length; i+=2){
sortedArray[i] = array[i/2];
sortedArray[i + 1] = array[array.length - i/2 - 1];
}
System.out.println(Arrays.toString(sortedArray)); // prints [0, 7, 1, 6, 2, 5, 3, 4]
This creates the final array by setting two values at a time:
every even index of the result array is mapped with the first values of the initial array
every odd index of the result array is mapped with the last values of the initial array
Here's a recursive approach to it, and improvements exist.
Motivation: Work your way through the array until you're left with only two values to compare. Once you're done, simply print them. Otherwise, print the value and continue slicing the array. We use two index locations to help us walk through the array, as each one governs its end of the array. We cease recursion when the difference between our start and end index is 1.
Steps to guard against silly things, like a zero-length array, I leave as an exercise for the reader.
public static void arrangeArray(int[] array) {
arrangeArray(array, 0, array.length - 1);
}
private static void arrangeArray(int[] array, int startIndex, int endIndex) {
System.out.printf("[%d][%d]\t", array[startIndex], array[endIndex]);
if(endIndex - startIndex > 1) {
arrangeArray(array, startIndex + 1, endIndex - 1);
}
}
You can extend a List and then Override the way this List works with indices so 0 remains 0 but 1 becomes physically a 2 in your internal array.
If you implement this object correctly, Collections.sort() won't see the difference. Then you can add your methods to get the internal Array for whatever you have to do.
The advantage of this approach is performance. You don't have to scramble the list yourself in a secondary step.
class swap
{
public static void main(String args[])
{
int arr[]={0,1,2,3,4,5,6,7};
int sorted[]=new int[8];
int end=7;
int i=1,j;
for(int k=0;k<8;k++)
{
sorted[k]=arr[k];
}
for(j=1;j<8;j=j+2)
{
sorted[j]=arr[end];
end--;
}
for(j=2;j<8;j=j+2)
{
sorted[j]=arr[i];
i++;
}
for(int k=0;k<8;k++)
System.out.println(sorted[k]);
}
}

Arrays and enhanced for loops?

Can someone please explain what is going on in this method?
class test{
public static void main(String args[])
{
int[] x = new int[4];
int[] xy = new int[4];
//System.out.println(xy[0]);
for(int j : x) {
xy[j] += 1;
}
System.out.println(xy[0]); }}
So I thought that the enhanced for loop would be doing this
/**for(int j=0; j < x.length(); j++)
xy[j=0] = 1
xy[j=1]=1
xy[j=2]=1
xy[j=3]=1*/
but from what I've been reading, the enhanced for loop is doing for(int element:array). Still, I don't understand what the for loop in my method is actually doing. I have tried System.out.println() statements to check what was being put into the array xy, but it is either addresses or 0.
Thanks for all the help and apologizes if this is confusing.
For Each loop that you have used in here does assign j a value that is already assigned to array x (which in your case is 0 ).
As according to your case of x and xy array:-
x[0]=0; xy[0]=0
x[1]=0; xy[0]=0
x[2]=0; xy[0]=0
x[3]=0; xy[0]=0
Describing for each loop according to your program case:-
for(j : x)
This implies it will run for 4 times which is the length of your array x.
when running first time the following process will happen
j=x[0] (so j=0 coz x[0] according to your case)
xy[0]=xy[0]+1 (so now xy[0] value becomes 1)
Similarly
for the second run of for each
j=x[1] (so j=0 coz x[0] according to your case)
xy[0]=xy[0]+1 (so now xy[0] value becomes 2 as in previous for each run xy[0]=1)
So all in all finally you will have xy[0]=4 at the end of 4th run of for each loop.
Finally the print statement will print 4.
int[] x = new int[4];
This creates an array of 4 elements. Each element's value is 0.
for(int j : x) {
xy[j] += 1;
}
This iterates through all the values of x. At each iteration, j is the next element in x, but since all elements are initialized to 0, j is always 0. So, the 4 iterations increment xy[0].
Here in the advanced for loop, the int j does not represent the index. Rather it represents the values in the xy[] array. It is not possible to get the index of advanced for loop. If you want index, then you might have to use ordinary for loop.
Ex. If you have
xy[]={5,8,3,4};
for(int j:xy)
{
println(j);
}
then the output would be
5
8
3
4
It should be straight-forward to find out, if you trace through using debugger.
In brief, it is getting each value in x, and use the value as index to increment corresponding value in xy.
It will be more obvious if you initialize both array with meaningful values:
int[] x = {1,1,3,3}
int[] xy = new int[4]; // initialized to 0 by default
after your piece of code, you will find xy containing {0,2,0,2}.
You should understand how enhanced-for-loop is expanded for array:
for (T v : arr) {
// do something
}
is transformed to
for (int i = 0; i < arr.length; ++i) {
T v = arr[i];
// do something
}
Obviously your understanding on how enhanced for loop being expanded is wrong.
In your case you need only for-loop and not enhanced for-loop:
for(int j = 0 ; x.length > j; j ++) {
xy[j] += 1;
}
Problem with your code is that your loop traverse only at index 0 of xy hence you get xy as [4, 0, 0, 0]
int[] x = new int[4];//default values [0, 0, 0, 0]
int[] xy = new int[4]; //default values [0, 0, 0, 0]
for(int j : x) { // j is always 0
xy[j] += 1;// xy[0] += 1
}
You can use the for-loop instead:
for(int i = 0 ; x.length > i; i ++) {
xy[i] += 1;
}
If you want to still use for each then here is the example
a[]={1,2,3,4};
for(int i:a)
{
println(i);
}
Hope it helps!

Iterating an array from both ends using two indices

This is more of an self defined programming exercise than a real problem. I have an array of java.lang.Comparable items. I need to maintain two pointers (an index into the array i.e., int values) i,j . i starts at the beginning of array and moves right until it encounters an element which is less than or equal to the previous element. When it does it stops moving right and ends up pointing to the element which is out of order(element which is not greater than the previous). Similarly j starts at the end of the array and moves left until it finds an element which is not less than the previous.
Also, I need to make sure that the indices don't run out of the array i.e., i cannot go below 0 and j cannot go above arraylength-1
lets say we have an array of 5 elements.
i = 0;
j = 4;(which is the arraylength-1 )
if C,D,E,F,G is the array ,the final values of i and j will be
i = 4 and j = 0
if array is J,D,E,F,G ,the final values of i, j will be
i = 0 , j = 0
if array is B,C,A,D,G , final values of i,j will be
i = 2 , j = 1
I tried to code the logic for moving i to the right, using a while loop as below. I was able to get it working for the i pointer in two cases.
public class PointerMovement{
public static void ptrsPointToOutOfOrderElements(Comparable[] a){
int lo = 0;
int hi = a.length-1;
int i = lo;
int t=i+1;
int j = hi;
//only for moving i to the right .
while(less(a[i],a[t])){
if(t == hi){
i=t;
break;
}
i++;
t++;
}
i=t;
for(Comparable x:a){
System.out.print(x+",");
}
System.out.println();
System.out.println("bad element or end of array at i="+i+"==>"+a[i]);
}
private static boolean less(Comparable x,Comparable y){
return x.compareTo(y) < 0;
}
public static void main(String[] args) {
String[] a = new String[]{"C","D","E","F","G"};//works
//String[] a = new String[]{"B","C","A","D","G"};//works
//String[] a = new String[]{"J","D","E","F","G"};//fails!
ptrsPointToOutOfOrderElements(a);
}
}
My line of reasoning given below
I maintain i=0; and another variable t=i+1
when the while loop fails, less(a[i],a[t]) is false .We need to return a pointer to a[t] which is out of order. so i=t and return i.
if we reach right end of array, the test if(t == hi) passes and we assign i=t and now i points to end of array.
However, the code fails when the out of order element is in the 0th position in the array.
J,D,E,F,G
Instead of i (=0) we get i=1 because i=t is assgined.i ends up pointing to D instead of J.
Can someone point me in the right direction?
update:
this seems to work
public static void ptrsPointToOutOfOrderElements(Comparable[] a){
int lo = 0;
int hi = a.length-1;
int i = lo;
while(less(a[i],a[i+1])){
if(i+1 == hi){
break;
}
i++;
}
i++;
int j = hi;
while(less(a[j-1],a[j])){
if(j-1 == lo){
break;
}
j--;
}
j--;
for(Comparable x:a){
System.out.print(x+",");
}
System.out.println();
if(i>=j){
System.out.println("pointers crossed");
}
System.out.println("bad element or end of array at i="+i+"==>"+a[i]);
System.out.println("bad element or end of array at j="+j+"==>"+a[j]);
}
I do not think you have a problem:
String[] a = new String[]{"C","D","E","F","G"};//works, index should be 4 (but should it be so? It would indicate that G is out of order while it is not. I think you should return 5, indicating that none is out of order.
String[] a = new String[]{"B","C","A","D","G"};//works, index should be 2 as A is out of order
String[] a = new String[]{"J","D","E","F","G"};//works since the first out of order element is indeed D, with index 1
I have tried using simple for loop.
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
for (var i = 0, j = arr.length - 1; i <= j; i++, j--) {
console.log(arr[i] + ' , ' + arr[j]);
}
Output :
1 , 10
2 , 9
3 , 8
4 , 7
5 , 6

Categories