简体   繁体   中英

Java sorting array positive ascending to negative ascending

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

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 :)

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;
    }
}

Algo:

  1. Traverse the Array and Store positives in one and Negatives in another. O(i)

  2. Sort the positives array in ascending order. O(mLog(m))

  3. Sort the negatives indescending order. O(nLog(n))

  4. Create a final array of the size of the input.

  5. 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 :

  1. Find total count of positive and negative numbers.

  2. Create and store the positive and negative values in the respective arrays.

  3. Sort positive array in ascending order.

  4. Sort negative array in descending order.

  5. 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, ie −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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM