Java sorting array positive ascending to negative ascending - java

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.

Related

Sorting an array by number of digits in each element from largest to smallest using loops java

I'm trying to sort an array by the number of digits in each element from largest to smallest. This technically works but it seems to sort the array by value as well. For example, instead of printing out 1234 700 234 80 52, it should print 1234 234 700 52 80 as 234 is before 700 in the original array.
public class Sort {
public static void main(String[] args) {
//Initialize array
int [] arr = new int [] {52, 234, 80, 700, 1234};
int temp = 0;
//Displaying elements of original array
System.out.println("Elements of original array: ");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
//Sort the array in descending order
//Math function is used to find length of each element
for (int i = 0; i < arr.length; i++) {
for (int j = i+1; j < arr.length; j++) {
if(Math.log10(arr[i]) + 1 < Math.log10(arr[j]) + 1) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
System.out.println();
//Displaying elements of array after sorting
System.out.println("Elements of array sorted in descending order: ");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}
The easiest way to find the length of the number is to convert it into a String and then call the method length on it.
int number = 123;
String numberAsString = String.valueOf(number);
int length = numberAsString.length(); // returns 3
But you also could do it by division. The following method takes a number and divides by multiples of 10.
divide by 1 (we have at least a length of 1)
division by 10 > 0 (we have at least a length of 2)
division by 100 > 0 (we have at least a length of 3)
...
the variable i is used as dividend and the variable j is used as counter. j counts the length of the number.
As soon as number / i equals zero we return the counter value.
public int lengthOfNumber(int number) {
if (number == 0) {
return 1;
}
for (int i = 1, j = 0; ; i *= 10, j++) {
if (number / i == 0) {
return j;
}
}
}
There are multiple ways to sort the array. Here are some examples (I used the string version for comparing the values).
Use nested for-loop
public void sortArray(int[] array) {
for (int i = 0; i < array.length; i++) {
int swapIndex = -1;
int maxLength = String.valueOf(array[i]).length();
for(int j = i + 1; j < array.length; j++) {
int length2 = String.valueOf(array[j]).length();
if (maxLength < length2) {
maxLength = length2;
swapIndex = j;
}
}
if (swapIndex > -1) {
int temp = array[i];
array[i] = array[swapIndex];
array[swapIndex] = temp;
}
}
}
I used a variable swapIndex which is initialized with -1. This way we can avoid unnecessary array operations.
We take the first element in the outer for-loop and go through the rest of the array in the inner for-loop. we only save a new swapIndex if there is a number in the rest of the array with a higher length. if there is no number with a higher length, swapIndex remains -1. We do a possible swap only in the outer for-loop if necessary (if swapIndex was set).
Using Arrays.sort()
If you want to use Arrays.sort you need to convert your array from primitive type int to Integer.
public void sortArray(Integer[] array) {
Arrays.sort(array, (o1, o2) -> {
Integer length1 = String.valueOf(o1).length();
Integer length2 = String.valueOf(o2).length();
return length2.compareTo(length1);
});
}
Using a recursive method
public void sortArray(int[] array) {
for (int i = 0; i < array.length - 1; i++) {
String current = String.valueOf(array[i]);
String next = String.valueOf(array[i + 1]);
if (current.length() < next.length()) {
int temp = array[i];
array[i] = array[i + 1];
array[i + 1] = temp;
// here you do a recursive call
sortArray(array);
}
}
}

Rearrange int array so that all the negative numbers come before the positivite numbers

I am trying to write a method which takes an array of ints and then rearranges the numbers in the array so that the negative numbers come first. The array does not need to be sorted in any way. The only requirement is that the solution has to be linear and it does not use an extra array.
Input:
{1, -5, 6, -4, 8, 9, 4, -2}
Output:
{-5, -2, -4, 8, 9, 1, 4, 6}
Now as a noob in Java and programming in general I am not 100% sure on what is considered a linear solution, but my guess is that it has to be a solution that does not use a loop within a loop.
I currently have an awful solution that I know doesn't work (and I also understand why) but I can't seem to think of any other solution. This task would be easy if I were allowed to use a loop within a loop or an additional array but I am not allowed to.
My code:
public static void separateArray(int[] numbers) {
int i = 0;
int j = numbers.length-1;
while(i<j){
if(numbers[i] > 0){
int temp;
temp = numbers[j];
numbers[j] = numbers[i];
numbers[i] = temp;
System.out.println(Arrays.toString(numbers));
}
i++;
j--;
}
}
You only need to change one line to get it (mostly) working. But you need to change two lines to correctly handle zeroes in the input. I have highlighted both of these minimally necessary changes with "FIXME" comments below:
public static void separateArray(int[] numbers) {
int i = 0;
int j = numbers.length-1;
while(i<j){
if(numbers[i] > 0){ // FIXME: zero is not a "negative number"
int temp;
temp = numbers[j];
numbers[j] = numbers[i];
numbers[i] = temp;
}
i++; // FIXME: only advance left side if (numbers[i] < 0)
j--; // FIXME: only decrease right side if (numbers[j] >= 0)
}
}
Your approach with two pointers, i and j is a good start.
Think about the loop invariant that you immediately set up (vacuously):
Elements in the range 0 (inclusive) to i (exclusive) are negative;
Elements in the range j (exclusive) to numbers.length (exclusive) are non-negative.
Now, you want to be able to move i and j together until they pass each other, preserving the loop invariant:
If i < numbers.length and numbers[i] < 0, you can increase i by 1;
If j >= 0 and numbers[j] >= 0, you can decrease j by 1;
If i < numbers.length and j >= 0, then numbers[i] >= 0 and numbers[j] < 0. Swap them around.
If you keep applying this strategy until i == j + 1, then you end up with the desired situation, that:
numbers[a] < 0 for a in [0..i)
numbers[a] >= 0 for a in (j..numbers.length), also written as numbers[a] >= 0 for a in (i-1..numbers.length), also written as numbers[a] >= 0 for a in [i..numbers.length).
So, you've partitioned the array so that all negative numbers are on the left of the i-th element, and all non-negative numbers are at or to the right of the i-th element.
Hopefully, this algorithm should be easy to follow, and thus to implement.
A linear solution is a solution with a run-time complexity Big-Oh(n) also noted as O(n), in other words, you have to loop through the whole array only once. To sort in linear time you can try one of the following sorting algorithms:
Pigeonhole sort
Counting sort
Radix sort
Your code works only if all the negative numbers are located in the right half side and the positives in the left half. For example, your code swaps 6 with 9 which both are positives. So, it depends on the order of your the array elements. As scottb said, try do it by your hands first then you will notice where you did wrong. Moreover, print your array out of the while
//Move positive number left and negative number right side
public class ArrangeArray {
public static void main(String[] args) {
int[] arr = { -2, 1, -3, 4, -1, 2, 1, -5, 4 };
for (int i = 0; i < arr.length; i++) {
System.out.print(" " + arr[i]);
}
int temp = 0;
for (int i = 0; i < arr.length; i++) {
// even
if (arr[i] < 0) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] > 0) {
arr[j] = arr[i] + arr[j];
arr[i] = arr[j] - arr[i];
arr[j] = arr[j] - arr[i];
break;
}
}
}
}
System.out.println("");
for (int i = 0; i < arr.length; i++) {
System.out.print(" " + arr[i]);
}
}
}
There is simple program it will help you. In this program i have take temp array and perform number of item iteration. In that i have start fill positive value from right and negative from left.
public static void rearrangePositiveAndNegativeValues() {
int[] a = {10,-2,-5,5,-8};
int[] b = new int[a.length];
int i = 0, j = a.length -1;
for (int k = 0; k < a.length ; k++) {
if (a[k] > 0) {
b[j--] = a[k];
} else {
b[i++] = a[k];
}
}
System.out.println("Rearranged Values : ");
printArray(b);
}
package ArrayProgramming;
import java.util.ArrayList;
import java.util.Arrays;
public class RearrangingpossitiveNegative {
public static void main(String[] args) {
int[] arr= {-1,3,4,5,-6,6,8,9,-4};
ArrayList<Integer> al = new ArrayList<Integer>();
for (int i=0;i<arr.length;i++) {
if(arr[i]>0) {
al.add(arr[i]);
}
}
for (int i=arr.length-1;i>=0;i--) {
if(arr[i]<0) {
al.add(arr[i]);
}
}
System.out.println(al);
}
}
from array import *
size = int(input())
arr = (array('i' , list(map(int, input().split()))))
negarr = array('i')
posarr = array('i')
for i in arr:
if i>=0:
posarr.append(i)
else:
negarr.append(i)
print(*(negarr+posarr))
we can also do it by creating two new arrays and adding elements into them as per given condition. later joining both of them to produce final result.

Java - how to stop nested loops from checking same indices twice?

Given an array and a number N call a pair of numbers from the array a Perfect Pair if their sum is equal to N.
Find all of the perfect pairs and return the sum of their indices. Note that any element of the array can only be counted in one Perfect Pair.
Examples
pairwise([1, 4, 2, 3, 0, 5], 7) = 11
Since the Perfect Pairs are (4, 3) and (2, 5) with indices 1 + 3 + 2 + 5 = 11.
pairwise([1, 3, 2, 4], 4) = 1
Since the element at index 0 (i.e. 1) and the element at index 1 (i.e. 3) form the only Perfect Pair.
Input 1 (arr) → array.integer :
array of non-negative integers
Input 2 (N) → integer :
positive integer
Output → integer :
sum of indices and 0 if no Perfect Pair exists
My Code:
public static void main(String[] args) {
int x[] = {1,4,2,3,0,5};
System.out.println(pairwise(x, 7));
}
public static int pairwise(int[] arr, int N) {
int t=0;
for(int i=0;i<arr.length;i++){
for(int k=0;k<arr.length;k++){
if(arr[i]+arr[k] == N){
t+=i+k;
}
}
}
return t;
}
The problem is my code checks indices twice, like (0,1) and (1,0) are treated like different indices.
The simplest options is to not check these in the first place. I assume i == k is not valid so you don't want to check k < i either.
public static void main(String[] args) {
int x[] = {1, 4, 2, 3, 0, 5};
System.out.println(pairwise(x, 7));
}
public static int pairwise(int[] arr, int N) {
int t = 0;
for (int i = 0; i < arr.length - 1; i++) {
for (int k = i + 1; k < arr.length; k++) {
if (arr[i] + arr[k] == N) {
t += i + k;
arr[i] = arr[k] = Integer.MIN_VALUE; // don't use these again
continue;
}
}
}
return t;
}
prints
11
This ensures you won't go over the same numbers twice.
Note: this is an O(n^2) approach, if you have more numbers you will want an O(n) approach which means using a set or map of numbers.
// O(n)
Map<Integer, Integer> intToIndex = new HashMap<>();
for(int i = 0; i < arr.length; i++)
intToIndex.put(arr[i], i);
// O(n)
for(int i = 0; i < arr.length; i++) {
int numberToLookFor = N - arr[i];
Integer k = intToIndex.get(numberToLookFor);
if (k != null) {
assert arr[i] + arr[k] == N;
// do something with i and k
}
}
Start the second loop from i, not 0.
for(int i = 0; i < 10; i++)
{
for(int j = i; j < 10; j ++)
{
System.out.println("(" + i + "," + j + ")");
}
}
Output:
I reduced `10` to `4`.
(0,0)
(0,1)
(0,2)
(0,3)
(0,4)
(1,1)
(1,2)
(1,3)
(1,4)
(2,2)
(2,3)
(2,4)
(3,3)
(3,4)
(4,4)

How I can print largest sum in this Program?

package Message;
public class Example_R {
public static void main (String args[])
int n=1;
int input[]={1, 2, 1, 3, 4};
for (int j=0; j<=4; j++) {
int Add = 0;
for (int i=0; i<=4; i++) {
if (input[j] !=input[i]) {
Add+=input[i];
}
}
System.out.println(Add);
}
}
}
Output of This program is: 9 9 9 8 7 sum of all the other elements in the array that are not equal to the element.
Now I want to extend the program so I can print the Largest sum of any of it's element, (In this case 9 is the largest sum.) Do you have any suggestions? For this assignment I am restricted from using additional array, hashmap etc. not allowed. Arrays.sort(..)
Hint: use a variable that is holding "the largest sum reached so far". You will update it very time you compute a new sum.
You will need to find "how and when do I initialize this variable ?" and "how do I update it ?"
You probably want to create a separate method that you pass your "input[]" array to (left as an exercise). However when considering problems like this, first just consider how you would do it in english (or whatever your native language is). Write down that strategy (an "algorithm") and then implement that in Java.
public class Example_R {
public static void main(String args[]) {
int input[] = { 1, 2, 1, 3, 4 };
int largestSum = 0;
int currentSum;
for (int j = 0; j < input.length; j++) {
currentSum = 0;
for (int i = 0; i < input.length; i++) {
if (input[j] != input[i]) {
currentSum += input[i];
}
}
System.out.println("Sum of all values not equal to " + input[j]
+ " is: " + currentSum);
if (j == 0) {
largestSum = currentSum;
} else {
if (largestSum < currentSum) {
largestSum = currentSum;
}
}
}
System.out.println("The largest overall sum was " + largestSum);
}
}
You'll need a temporary variable to save the current highest number.
int temp = intArray[0]
for(int i : intArray)
{
if(i > temp)
temp = i;
}
Try this:
int n = 1,sum=0;
int[] input = { 1, 2, 1, 3, 4 };
for (int j = 0; j <= 4; j++){
int Add = 0;
for (int i = 0; i <= 4; i++){
if (input[j] != input[i])
Add += input[i];
}
if (sum < Add)
sum = Add;
}
After completing the second loop every time,the "sum" was updated if it is less than the current "add" value.
You can use variables of type Comparable and use the compareTo() method.
one.compareTo(two) will return > 0 if one > two
one.compareTo(two) will return < 0 if one < two
one.compareTo(two) will return 0 if one and two are equal
Go through the array, compare the current index with the previous index, and update a variable that holds the currentLargest value.

Sort an array by remainder of 4

I have an exercise in which I have to sort an array in the following way:
the numbers that divide 4 with no remainder will be the first in the array (e.g 4,8,12,16).
the numbers that divide 4 with remainder of 1 will be the second in the array (1,5,9).
the numbers that divide 4 with remainder of 2 will be the third in the array (2,6,10).
the numbers that divide 4 with remainder of 3 will be last in the array.
For example, the following array:
int []a={1,7,3,2,4,1,8,14}
will be:
4 8 1 1 2 14 3 7
the order within the groups does not matter.
I have found a solution which works on O(n) time complexity and O(1) space complexity.
However, it is ugly and moves on the array 3 times. I would want a more elegant solution.
This is my code:
int ptr=a.length-1; int temp=0, i=0;
while (i<ptr){
//move 3 remained to the end
if (a[i] % 4==3){
temp=a[ptr];
a[ptr]=a[i];
a[i]=temp;
ptr--;
}
else
i++;
}
i=0;
while (i<ptr){
if (a[i]%4==2)
{
temp=a[ptr];
a[ptr]=a[i];
a[i]=temp;
ptr--;
}
else
i++;
}
i=0;
while (i<ptr){
if (a[i]%4==1)
{
temp=a[ptr];
a[ptr]=a[i];
a[i]=temp;
ptr--;
}
else
i++;
}
Important to know:
I don't want time complexity worse than O(n), and space complexity worse than O(1).
Since O(3 * N) is O(N), you only need to loop through the array three times:
Move the elements e % 4 == 0 to the front, swapping elements along the way;
Move the elements e % 4 == 1 to the front, swapping elements along the way;
Move the elements e % 4 == 2 to the front, swapping elements along the way;
The elements that e % 4 == 3 will be at the end after this.
Example:
public static void main(String args[]) {
int[] a = { 1, 7, 3, 2, 4, 1, 8, 14 , 9};
int current = 0;
for (int i = 0; i < 3; i++) {
for (int j = current; j < a.length; j++) {
if (a[j] % 4 == i) {
int b = a[j];
a[j] = a[current];
a[current] = b;
current++;
}
}
}
System.out.println(Arrays.toString(a));
}
Just use a comparator and make use for the very efficient internal sort algorithm.
Arrays.sort(a, new Comparator() {
public int compare(int a, int b) {
if(a%4 == b%4) {
if(a < b) return -1;
if(a > b) return 1;
return 0;
} else {
if(a%4 < b%4) return -1;
if(a%4 > b%4) return 1;
return 0;
}
}
});
You can use up more memory. This is not correct, but I will still put it.
int modulusLength = 4;
List<Integer> array[] = new List<Integer>[modulusLength];
for(int i = 0; i < modulusLength; i++)
array[i] = new ArrayList<Integer>;
for(int i = 0 ; i < a.length; i++)
array[a[i]%modulusLength].put(a[i]);
int counter = 0;
for(int i = 0 ; i < array.length; i++)
for(int j = 0; j < array[i].size; j++)
{
a[counter] = array[i].get(j);
counter++;
}
Horrible and scary, but was fun to write. And it works :)

Categories

Resources