This is what I need to do
Ability to reverse the contents of a single dimensional array of variable size, without using another temporary array.
Given a single dimensional array of integers, numbers, write the Java code to reverse the contents of numbers in-place without using a temporary array to store the reversed contents.
For example, if numbers is {12, 34, 50, 67, 88}, provide code that will alter numbers so that its contents now become {88, 67, 50, 34, 12}.
This is what I have
it is not working correctly.
public static int[] reverseArrayWithoutTempArray(int[] array) {
double array [ ];
array = new double [10];
int [ ] num = {12, 34, 50, 67, 88};
int i = 0;
int j = a.length - 1;
for (i = 0; i < a.length / 2; i++, j—){
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
return array;
}
It actually is working correctly for the example you provided. This is how my code looks like:
public static int[] reverseArrayWithoutTempArray(int[] a) {
int i = 0;
int j = a.length - 1;
for (i = 0; i < a.length / 2; i++, j--){
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
return a;
}
That's it:
public static void reverseArrayWithoutTempArray(int[] num) {
int j = num.length - 1;
for (int i = 0; i < num.length / 2; i++, j --){
int temp = num[i];
num[i] = num[j];
num[j] = temp;
}
}
Calling of this method will be like:
int [] num = {12, 34, 50, 67, 88};
reverseArrayWithoutTempArray(num);
System.out.println(Arrays.toString(num)); //to log
You're basic algorithm is correct, but you code is a complete mess.
array is declared twice, once as a method parameter and once as a local variable. Get rid of the local reference.
The array num is ignored and isn't needed any way, get rid of it.
I don't know if it's a typo or not, but j— should be j--
does this work? (swap method is not implemented, but you know how to do it ,right?)
public static void reverseIntArray(int[] input) {
final int last = input.length - 1;
if (last < 0) {
return;
}
for (int i = 0; i < input.length / 2 + 1; i++) {
if (last - i <= i) {
return;
}
swap(input, i, last - i);
}
}
If this isn't coursework, you can use ArrayUtils.reverse.
Assuming you know how to implement swap the following reverses a part of array in-place:
public void reverse(int[] a, int low, int hi) {
while (low < hi) {
swap(low++, hi--, a);
}
}
You can then reverse the entire array by calling reverse(a, 0, a.length - 1).
Related
I can't solve the problem , where I need output from array A like {1,2,3,4,-1,-2,-3,-4}
from random numbers in array, then write it to another array B. So far my experimental code doesn't work as I'd
public static void main(String[] args) {
int a[] = {5,4,3,2,1,-3,-2,-30};
int length = a.length - 1;
for (int i = 0 ; i < length ; i++) {
for (int j = 0 ; j < length-i ; j++) {
if (a[j] < a[j+1]) {
int swap = a[j];
a[j] = a[j+1];
a[j+1] = swap;
}
}
}
for (int x : a) {
System.out.print(x+" ");
}
}
Output is 5 4 3 2 1 -2 -3 -30 , but I need 1,2,3,4,5,-2,-3,-30
Update:
public static void main(String[] args) {
int a[] = {5,4,3,2,1,-3,-2,-30,-1,-15,8};
int length = a.length - 1;
for (int i = 0 ; i < length ; i++) {
for (int j = 0 ; j < length-i ; j++) {
if (a[j] < a[j+1]) {
int swap = a[j];
a[j] = a[j+1];
a[j+1] = swap;
} else {
if (a[j] > a[j+1] && a[j+1] > 0) {
int swap = a[j];
a[j] = a[j+1];
a[j+1] = swap;
}
}
}
}
for (int x : a) {
System.out.print(x+" ");
}
}
I got closer to my target but 8 1 2 3 4 5 -1 -2 -3 -15 -30 , that number 8 ruins it all
Add an if-else to differentiate the positive and negative case.
if (a[j] < 0) {
if (a[j] < a[j+1]) {
int swap = a[j];
a[j] = a[j+1];
a[j+1] = swap;
}
} else {
if (a[j] > a[j+1] && a[j+1] > 0) {
int swap = a[j];
a[j] = a[j+1];
a[j+1] = swap;
}
}
If I understand you correctly you want to sort after two things. Positive numbers from low to high and negative numbers from high to low.
You could first sort from high to low and in a second run over the array skip all positives and then sort from high to low.
Does this help?
I could write some code, but I believe that's something you want to learn right now :)
Algo:
Traverse the Array and Store positives in one and Negatives in another. O(i)
Sort the positives array in ascending order. O(mLog(m))
Sort the negatives indescending order. O(nLog(n))
Create a final array of the size of the input.
Add all the positive array sorted values. Then add the negative array sorted values. O(i)
Total : O(i) + O(mLog(m)) + O(nLog(n)) + O(i) = O(mLog(m)) if m > n
I have used library functions here. But if you want you can the write the functions using the same idea.
public class PostivieAsendingNegativeDesending implements Comparator<Integer> {
public static void main(String args[]) {
int fullList[] = {5, 4, 3, 2, 1, -3, -2, -30};
ArrayList<Integer> subList = new ArrayList<>();
ArrayList<Integer> subList2 = new ArrayList<>();
for (int i = 0; i < fullList.length; i++) {
if (fullList[i] < 0) {
subList2.add((fullList[i]));
} else {
subList.add(fullList[i]);
}
}
Collections.sort(subList);
Collections.sort(subList2, new PostivieAsendingNegativeDesending());
subList.addAll(subList2);
for (int i = 0; i < subList.size(); i++) {
System.out.print(subList.get(i) + " ");
}
System.out.println("");
}
#Override
public int compare(Integer n1, Integer n2) {
return n2 - n1;
}
}
This will do the trick which uses only basic loops
public static void main(String[] args) {
int a[] = { 5, 4, 3, 2, 1, -3, -2, -30 };
int length = a.length - 1;
int pos = 0, neg = 0;
// find total count of positive and negative numbers
for (int i = 0; i <= length; i++) {
if (a[i] < 0)
neg++;
else
pos++;
}
// initialize the arrays based on 'pos' and 'neg'
int posArr[] = new int[pos];
int negArr[] = new int[neg];
// store pos and neg values in the arrays
int countPos = 0, countNeg = 0;
for (int i = 0; i <= length; i++) {
if (a[i] < 0) {
negArr[countNeg] = a[i];
countNeg++;
} else {
posArr[countPos] = a[i];
countPos++;
}
}
// sort positive numbers
for (int i = 0; i < posArr.length - 1; i++) {
for (int j = 0; j < posArr.length - 1 - i; j++) {
if (posArr[j] > posArr[j + 1]) {
int swap = posArr[j];
posArr[j] = posArr[j + 1];
posArr[j + 1] = swap;
}
}
}
// sort negative numbers
for (int i = 0; i < negArr.length - 1; i++) {
for (int j = 0; j < negArr.length - 1 - i; j++) {
if (negArr[j] < negArr[j + 1]) {
int swap = negArr[j];
negArr[j] = negArr[j + 1];
negArr[j + 1] = swap;
}
}
}
// 1. print out posArr[] and then negArr[]
// or
// 2. merge them into another array and print
}
Logic is explained below :
Find total count of positive and negative numbers.
Create and store the positive and negative values in the respective arrays.
Sort positive array in ascending order.
Sort negative array in descending order.
Print out positive array followed by the negative array OR merge them into another and print.
I suggest another approach. You should try to formulate the rules to which the exact comparison must adhere.
Your requirement seem to have the following rules:
Positive numbers always come before negative numbers.
Positive numbers are ordered in ascending order.
Negative numbers are ordered in descending order. Yes, I said descending. Since higher numbers come before lower numbers, i.e. −2 is greater than −7.
Warning: you are using a nested for loop, which means that the process time will grow exponentially if the array becomes larger. The good news is: you don't need to nest a for loop into another for loop. I suggest writing a Comparator instead:
// The contract of Comparator's only method 'compare(i, j)' is that you
// return a negative value if i < j, a positive (nonzero) value if i > j and
// 0 if they are equal.
final Comparator<Integer> c = (i, j) -> { // I'm using a lambda expression,
// see footnote
// If i is positive and j is negative, then i must come first
if (i >= 0 && j < 0) {
return -1;
}
// If i is negative and j is positive, then j must come first
else if (i < 0 && j >= 0) {
return 1;
}
// Else, we can just subtract i from j or j from i, depending of whether
// i is negative or positive
else {
return (i < 0 ? j - i : i - j);
}
}
Your code could look like this:
int[] a = { 5, 4, 3, 2, 1, -3, -2, -30 };
int[] yourSortedIntArray = Arrays.stream(a)
.boxed()
.sorted(c) // Your Comparator, could also added inline, like
// .sorted((i, j) -> { ... })
.mapToInt(i -> i)
.toArray();
Lambda expressions are a new concept from Java 8. The Java Tutorials provide some valuable information.
So I have a problem, this method is supposed to sort an array of integers by using counting sort. The problem is that the resulting array has one extra element, zero. If the original array had a zero element (or several) it's fine, but if the original array didn't have any zero elements the result starts from zero anyway.
e.g. int input[] = { 2, 1, 4 }; result -> Sorted Array : [0, 1, 2, 4]
Why would this be happening?
public class CauntingSort {
public static int max(int[] A)
{
int maxValue = A[0];
for(int i = 0; i < A.length; i++)
if(maxValue < A[i])
maxValue = A[i];
return maxValue;
}
public static int[] createCountersArray(int[] A)
{
int maxValue = max(A) + 1;
int[] Result = new int[A.length + 1];
int[] Count = new int[maxValue];
for (int i = 0; i < A.length; i++) {
int x = Count[A[i]];
x++;
Count[A[i]] = x;
}
for (int i = 1; i < Count.length; i++) {
Count[i] = Count[i] + Count[i - 1];
}
for (int i = A.length -1; i >= 0; i--) {
int x = Count[A[i]];
Result[x] = A[i];
x--;
Count[A[i]] = x;
}
return Result;
}
}
You are using int[] Result = new int[A.length + 1]; which makes the array one position larger. But if you avoid it, you'll have an IndexOutOfBounds exception because you're supposed to do x-- before using x to access the array, so your code should change to something like:
public static int[] createCountersArray(int[] A)
{
int maxValue = max(A) + 1;
int[] Result = new int[A.length];
int[] Count = new int[maxValue];
for (int i = 0; i < A.length; i++) {
int x = Count[A[i]];
x++;
Count[A[i]] = x;
}
for (int i = 1; i < Count.length; i++) {
Count[i] = Count[i] + Count[i - 1];
}
for (int i = A.length -1; i >= 0; i--) {
int x = Count[A[i]];
x--;
Result[x] = A[i];
Count[A[i]] = x;
}
return Result;
}
Here you go: tio.run
int maxValue = max(A) + 1;
Returns the highest value of A + 1, so your new array with new int[maxValue] will be of size = 5;
The array Result is of the lenght A.lenght + 1, that is 4 + 1 = 5;
The first 0 is a predefinied value of int if it is a ? extends Object it would be null.
The leading 0 in your result is the initial value assigned to that element when the array is instantiated. That initial value is never modified because your loop that fills the result writes only to elements that correspond to a positive number of cumulative counts.
For example, consider sorting a one-element array. The Count for that element will be 1, so you will write the element's value at index 1 of the result array, leaving index 0 untouched.
Basically, then, this is an off-by-one error. You could fix it by changing
Result[x] = A[i];
to
Result[x - 1] = A[i];
HOWEVER, part of the problem here is that the buggy part of the routine is difficult to follow or analyze (for a human). No doubt it is comparatively efficient; nevertheless, fast, broken code is not better than slow, working code. Here's an alternative that is easier to reason about:
int nextResult = 0;
for (int i = 0; i < Count.length; i++) {
for (int j = 0; j < Count[i]; j++) {
Result[nextResult] = i;
nextResult++;
}
}
Of course, you'll also want to avoid declaring the Result array larger than array A.
I am having problem printing the array after changes. The code is supposed to contain an array, and then I insert a number which is supposed to become the index number (this case 4). That number is then taken and moved to the back of the array, while all the other numbers move one index higher up in the array to fill the empty spot. For some reason it doesn´t allow me to print the array after making the changes.
public static int SendaAftast(int a[], int i) {
for(int k = 0; k <a.length; k++) {
int temp = a[k];
while(k <a.length) {
a[k] = a[k] - 1;
}
a[a.length] = temp;
}
return a[i];
}
public static void main(String[] args) {
int[] a = new int [20];
for(int i = 0; i < a.length; i++) {
a[i] = (int)(Math.random()*a.length)+1;
}
System.out.println(SendaAftast(a, 4));
1. Infinite loop
You don't get anything printed because you have an infinite loop in your code which is:
while(k < a.length) {
a[k] = a[k] - 1;
}
If the condition k < a.length is true it will always be true since you never change its state within the loop in other words k is never modified in this loop it is only modified outside and a.length never changes either.
2. ArrayIndexOutOfBoundsException
The second issue in your code is a[a.length] = temp; which will throw a ArrayIndexOutOfBoundsException if reached because the index of an array goes from 0 to a.length - 1.
3. The new code of SendaAftast
Moreover your method SendaAftast doesn't seem to be properly written, as far as I understand your context, it should rather be something like this:
public static int SendaAftast(int a[], int i) {
int temp = a[i];
// Move everything from i to a.length - 2
for(int k = i; k < a.length - 1; k++) {
a[k] = a[k + 1];
}
// Set the new value of the last element of the array
a[a.length - 1] = temp;
return a[i];
}
Or even faster with a System.arraycopy(src, srcPos, dest, destPos, length):
public static int SendaAftast(int a[], int i) {
int temp = a[i];
// Move everything from i to a.length - 2
System.arraycopy(a, i + 1, a, i, a.length - 1 - i);
// Set the new value of the last element of the array
a[a.length - 1] = temp;
return a[i];
}
4. How to print an array?
To print an array, you must first convert it as a String and the easiest way to do it, is with Arrays.toString(myArray) so you can print it like this:
System.out.println(Arrays.toString(a));
public static int SendaAftast(int a[], int i) {
int temp = a[i];
for (int k = i; k < a.length-1; k++) {
a[k] = a[k+1] ;
}
a[a.length - 1] = temp;
return a[i];
}
Your SendaAftast should look like this. The inner while loop was useless,and also the reason for your the infinite loop that made your program not print. Also variable 'a' cannot be indexed by its own size as counting in an array starts from 0 - a.length-1,hence to get the last value of the array you should use a[a.length-1] and not a[a.length].
Change the line:
a[k] = a[k] - 1;
to
a[k] = a[k-1];
Bye!
So I know how to get the size of a combination - factorial of the size of the array (in my case) over the size of the subset of that array wanted. The issue I'm having is getting the combinations. I've read through most of the questions so far here on stackoverflow and have come up with nothing. I think the issue I'm finding is that I want to add together the elements in the combitorial subsets created. All together this should be done recursively
So to clarify:
int[] array = {1,2,3,4,5};
the subset would be the size of say 2 and combinations would be
{1,2},{1,3},{1,4},{1,5},{2,3},{2,4},{2,5},{3,4},{3,5},{4,5}
from this data I want to see if the subset say... equals 6, then the answers would be:
{1,5} and {2,4} leaving me with an array of {1,5,2,4}
so far I have this:
public static int[] subset(int[] array, int n, int sum){
// n = size of subsets
// sum = what the sum of the ints in the subsets should be
int count = 0; // used to count values in array later
int[] temp = new temp[array.length]; // will be array returned
if(array.length < n){
return false;
}
for (int i = 1; i < array.length; i++) {
for (int j = 0; j < n; j++) {
int[] subset = new int[n];
System.arraycopy(array, 1, temp, 0, array.length - 1); // should be array moved forward to get new combinations
**// unable to figure how how to compute subsets of the size using recursion so far have something along these lines**
subset[i] = array[i];
subset[i+1] = array[i+1];
for (int k = 0; k < n; k++ ) {
count += subset[k];
}
**end of what I had **
if (j == n && count == sum) {
temp[i] = array[i];
temp[i+1] = array[i+1];
}
}
} subset(temp, n, goal);
return temp;
}
How should I go about computing the possible combinations of subsets available?
I hope you will love me. Only thing you have to do is to merge results in one array, but it checks all possibilities (try to run the program and look at output) :) :
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5};
int n = 2;
subset(array, n, 6, 0, new int[n], 0);
}
public static int[] subset(int[] array, int n, int sum, int count, int[] subarray, int pos) {
subarray[count] = array[pos];
count++;
//If I have enough numbers in my subarray, I can check, if it is equal to my sum
if (count == n) {
//If it is equal, I found subarray I was looking for
if (addArrayInt(subarray) == sum) {
return subarray;
} else {
return null;
}
}
for (int i = pos + 1; i < array.length; i++) {
int[] res = subset(array, n, sum, count, subarray.clone(), i);
if (res != null) {
//Good result returned, so I print it, here you should merge it
System.out.println(Arrays.toString(res));
}
}
if ((count == 1) && (pos < array.length - 1)) {
subset(array, n, sum, 0, new int[n], pos + 1);
}
//Here you should return your merged result, if you find any or null, if you do not
return null;
}
public static int addArrayInt(int[] array) {
int res = 0;
for (int i = 0; i < array.length; i++) {
res += array[i];
}
return res;
}
You should think about how this problem would be done with loops.
for (int i = 0; i < array.length - 1; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[i] + array[j] == sum) {
//Add the values to the array
}
}
}
Simply convert this to a recursive code.
The best way I can think to do this would be to have each recursive call run on a subset of the original array. Note that you don't need to create a new array to do this as you are doing in your code example. Just have a reference in each call to the new index in the array. So your constructor might look like this:
public static int[] subset(int[] array, int ind, int sum)
where array is the array, ind is the new starting index and sum is the sum you are trying to find
So I am not sure why this is becoming so hard for me, but I need to sort high to low and low to high.
For high to low I have:
int a, b;
int temp;
int sortTheNumbers = len - 1;
for (a = 0; a < sortTheNumbers; ++a) {
for (b = 0; b < sortTheNumbers; ++b) {
if (array[b] < array[b + 1]) {
temp = array[b];
array[b] = array[b + 1];
array[b + 1] = temp;
}
}
}
However, I can't for the life of me get it to work in reverse (low to high), I have thought the logic through and it always returns 0's for all the values.
Any help appreciated!
The bigger picture is that I have a JTable with 4 columns, each column with entries of numbers, names, or dates. I need to be able to sort those back and forth.
Thanks!
Unless you think using already available sort functions and autoboxing is cheating:
Integer[] arr =
{ 12, 67, 1, 34, 9, 78, 6, 31 };
Arrays.sort(arr, new Comparator<Integer>()
{
#Override
public int compare(Integer x, Integer y)
{
return x - y;
}
});
System.out.println("low to high:" + Arrays.toString(arr));
Prints low to high:[1, 6, 9, 12, 31, 34, 67, 78]
if you need high to low change x-y to y-x in the comparator
You are never visiting the last element of the array.
Also, you should be aware that bubble sort is pretty inefficent and you could just use Arrays.sort().
public class sorting {
public static void main(String arg[])throws Exception{
int j[]={1,28,3,4,2}; //declaring array with disordered values
for(int s=0;s<=j.length-1;s++){
for(int k=0;k<=j.length-2;k++){
if(j[k]>j[k+1]){ //comparing array values
int temp=0;
temp=j[k]; //storing value of array in temp variable
j[k]=j[k+1]; //swaping values
j[k+1]=temp; //now storing temp value in array
} //end if block
} // end inner loop
}
//end outer loop
for(int s=0;s<=j.length-1;s++){
System.out.println(j[s]); //retrieving values of array in ascending order
}
}
}
You just need to write one string Arrays.sort(arr) for low to high for Java 8.
Arrays.sort(arr, Collections.reverseOrder()) for high to low
The only thing you need to do to change the sort order is change
if (array[b] < array[b + 1])
to
if (array[b] > array[b + 1])
Although, as others have noted, it's very inefficient! :-)
In java8 you can do something like this:
temp.stream()
.sorted((e1, e2) -> Integer.compare(e2, e1))
.forEach(e -> System.out.println(e));
You need a more efficient sort. like mergesort. try www.geekviewpoint.com and go to sort
If you just want sort the int array: Use the quicksort... It's not a lot of code and it's N*lgN in avarage or N^2 in worst-case.
To sort multiple data, use the Java Compare (as above) or a stable sorting algorithm
static void quicksort(int[] a,int l, int r){
if(r <= l) return;
int pivot = partition(a,l,r);
//Improvement, sort the smallest part first
if((pivot-l) < (r-pivot)){
quicksort(a,l,pivot-1);
quicksort(a,pivot+1,r);
}else{
quicksort(a,pivot+1,r);
quicksort(a,l,pivot-1);
}
}
static int partition(int[] a,int l,int r){
int i = l-1;
int j = r;
int v = a[r];
while(true){
while(less(a[++i],v)); //-> until bigger
while((less(v,a[--j]) && (j != i))); //-> until smaller and not end
if(i >= j){
break;
}
exch(a,i,j);
}
exch(a,i,r);
return i;
}
If you want to apply same logic as what you have done...by not using Arrays.sort...then following will help
int[] intArr = {5, 4, 3, 8, 9, 11, 3, 2, 9, 8, 7, 1, 22, 15, 67, 4, 17, 54};
//Low to high
for(int j=0; j<intArr.length-1; j++){
for(int i=0; i<intArr.length-1; i++){
if (intArr[i] > intArr[i+1]){
int temp = intArr[i+1];
intArr[i+1] = intArr[i];
intArr[i] = temp;
}
}
}
//High to low
for(int j=0; j<intArr.length-1; j++){
for(int i=0; i<intArr.length-1; i++){
if (intArr[i] < intArr[i+1]){
int temp = intArr[i+1];
intArr[i+1] = intArr[i];
intArr[i] = temp;
}
}
}
for(int ars : intArr){
System.out.print(ars+",");
}
Let me know if this works:
public class prog1 {
public static void main (String args[]){
int a[] = {1,22,5,16,7,9,12,16,18,30};
for(int b=0; b<=a.length;b++){
for(int c=0; c<=a.length-2;c++){
if(a[c]>a[c+1]){
int temp=0;
temp=a[c];
a[c]=a[c+1];
a[c+1]=temp;
}
}
}
for(int b=0;b<a.length;b++){
System.out.println(a[b]);
}
}
}
You can try with bubble sort: Example shown below
int[] numbers = { 4, 7, 20, 2, 56 };
int temp;
for (int i = 0; i < numbers.length; i++)
{
for(int j = 0; j < numbers.length; j++)
{
if(numbers[i] > numbers[j + 1])
{
temp = numbers [j + 1];
numbers [j + 1]= numbers [i];
numbers [i] = temp;
}
}
}
for (int i = 0; i < numbers.length; i++)
{
System.out.println(numbers[i].toString());
}