1

I already arrange non-negative numbers to the left side of the array, now I want to put the sort function to rearrange numbers in ascending order into my program but it didn't work, I can't have them both, can you all help please? I'm totally new to this.

int tg;
    for(int i = 0; i < n - 1; i++){
        for(int j = i + 1; j < n; j++){
            if(a[i] > a[j]){
                tg = a[i];
                a[i] = a[j];
                a[j] = tg;        
            }
        }
    }
#include<bits/stdc++.h> 
using namespace std; 
  
void segregateElements(int arr[], int n) 
{ 
    int temp[n]; 
    int j = 0; // index of temp 
    for (int i = 0; i < n ; i++) 
        if (arr[i] >= 0 ) 
            temp[j++] = arr[i]; 
    
    if (j == n || j == 0) 
        return; 

    for (int i = 0 ; i < n ; i++) 
        if (arr[i] < 0) 
            temp[j++] = arr[i]; 
  
    memcpy(arr, temp, sizeof(temp)); 
} 
  
int main() 
{ 
    int arr[] = {1 ,-1 ,-3 , -2, 7, 5, 11, 6 }; 
    int n = sizeof(arr)/sizeof(arr[0]); 
  
    segregateElements(arr, n); 
  
    for (int i = 0; i < n; i++) 
    cout << arr[i] << " "; 
  
    return 0; 
} 

Output:

1 7 5 11 6 -1 -3 -2

Expected:

1 5 6 7 11 -1 -2 -3
Marek R
  • 32,568
  • 6
  • 55
  • 140
berries
  • 15
  • 5
  • 2
    I strongly suggest learning [algorithms](https://en.cppreference.com/w/cpp/algorithm). A `partition` and 2 `sort`s will solve this problem in a 4-5 lines of code. Doing all these manual loops is very error prone, and hard to read/write. – cigien Jul 22 '22 at 03:34
  • See [Why should I not include ](https://stackoverflow.com/q/31816095/1553090) – paddy Jul 22 '22 at 03:35
  • Hi, I am following an online course and it hasn't get me to the algorithms yet, only these loops to solve problems – berries Jul 22 '22 at 03:40
  • and it said that I should solve the problem with some fundamentals first then they will teach basic algorithms later so that in the future I can easily learn other languages or advanced algorithms by myself – berries Jul 22 '22 at 03:43
  • So, it appears you already have the partitioning working. Now your sort function just needs to operate on a subset of an array instead of the entire array. Find the index of the first negative (or `n` if no negatives): `int firstNeg = figureThatOut();` and then sort the subarrays: `yourSort(arr, firstNeg); yourSort(arr+firstNeg, n-firstNeg);` – paddy Jul 22 '22 at 03:47
  • @berries `int temp[n];` -- If your online course teaches code like this, then drop the course immediately -- better yet, tell us where this online course is, so that others know not to go there. This is not valid C++. Arrays in C++ must have their size known at compile time, not runtime. Instead, this should be `std::vector temp(n);` – PaulMcKenzie Jul 22 '22 at 03:58
  • a course that tells you to use [`#include`](https://stackoverflow.com/q/31816095/995714) and [`using namespace std`](https://stackoverflow.com/q/1452721/995714) is just sh*tty. Find a better course – phuclv Jul 22 '22 at 04:01
  • 1
    Just for fun, here is a way to solve without using the algorithms library: https://godbolt.org/z/3djzcbhPc ... It intentionally doesn't make use of much C++ language features (e.g. templates for defining a more flexible sort function) and uses mostly code you've already supplied. However, it does use a technique for partitioning that requires no additional buffer. You may be interested in studying that. – paddy Jul 22 '22 at 04:25
  • 2
    @berries [Solution using partition and sort](https://godbolt.org/z/oa7b9qEz3). – PaulMcKenzie Jul 22 '22 at 04:27

4 Answers4

2

Expected: 1 5 6 7 11 -1 -2 -3

This means that the non-negative numbers are sorted in a ascending order and that the negative numbers are sorted in decending order.

In order to do this, I suggest using std::partition to put all the non-negative numbers first in the array and the negative numbers last, then std::sort the non-negative numbers in ascending order and std::sort the negative numbers in decending order.

Example:

#include <algorithm>  // partition, sort
#include <functional> // greater
#include <iostream>
#include <iterator>   // begin, end

int main() {
    int arr[] = {1, -1, -3, -2, 7, 5, 11, 6};

    // partition returns an iterator to the partition point:
    auto part = std::partition(std::begin(arr), std::end(arr),
                               [](int v) { return v >= 0; });

    // sort the non-negative numbers:
    std::sort(std::begin(arr), part);        // ascending order (the default)

    // sort the negative numbers:
    std::sort(part, std::end(arr), std::greater<int>{});   // decending order

    // print the result:
    for(int val : arr) std::cout << val << ' ';
    std::cout << '\n';
}

Output:

1 5 6 7 11 -1 -2 -3

Without partitioning first, you could also sort using a special comparator:

#include <algorithm> // sort
#include <iostream>
#include <iterator>  // begin, end

int main() {
    int arr[] = {1, -1, -3, -2, 7, 5, 11, 6};

    std::sort(std::begin(arr), std::end(arr), [](int l, int r) {
        if (l >= 0 && r >= 0) return l < r; // both non-negative, ascending
        return r < l;                       // all other cases, decending
    });

    // print the result:
    for (int val : arr) std::cout << val << ' ';
    std::cout << '\n';
}
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
0

You have two requirements:

  • sort array elements by ascending order
  • re-arrange non-negative numbers into the left part of the array

So you need to add left rotation after sorting is done. Check the following code:

#include<iostream>
using namespace std;

/*Function to get gcd of a and b*/
int gcd(int a, int b)
{
    if (b == 0)
        return a;

    else
        return gcd(b, a % b);
}

/*Function to left rotate arr[] of size n by d*/
void leftRotate(int arr[], int d, int n)
{
    /* To handle if d >= n */
    d = d % n;
    int g_c_d = gcd(d, n);
    for (int i = 0; i < g_c_d; i++) {
        /* move i-th values of blocks */
        int temp = arr[i];
        int j = i;

        while (1) {
            int k = j + d;
            if (k >= n)
                k = k - n;

            if (k == i)
                break;

            arr[j] = arr[k];
            j = k;
        }
        arr[j] = temp;
    }
}
void sortElements(int a[], int n)
{
    int tg;
    for(int i = 0; i < n - 1; i++){
        for(int j = i + 1; j < n; j++){
            if(a[i] > a[j] && a[i]){
                tg = a[i];
                a[i] = a[j];
                a[j] = tg;
            }
        }
    }
    int pivot = -1;

    for(int i=0; i < n; i++){
        if(a[i] >= 0){
            pivot = i;
            break;
        }
    }
    leftRotate(a, pivot, n);

}

int main()
{
    int arr[] = {1, 6, -5, 2, 3, 11, -7, -1};
    int n = sizeof(arr)/sizeof(arr[0]);

    sortElements(arr, n);

    for (int i = 0; i < n; i++)
    cout << arr[i] << " ";

    return 0;
}

samnoon
  • 1,340
  • 2
  • 13
  • 23
0

Well, I think this is a good exercise for anyone learning C.

Yes, as other buddies mentioned, you may go with the 'partition then partial sort' approach.

But since 'pointer of function' is a key function of C, you will face it sooner or later, now it is a good point to take a glimpse to it.

When 'sorting', it important to define 'which one is greater'. Like

#include  <stdio.h> 
#include  <string.h>

int normal_is_greater(int a, int b){
    return a > b;
}

void plain_buble(int arr[], int n)
{   // as the name says, this is a 'plain buble sort'
    int i,j;
    for (i=0; i< n; i++) {
        for (j = 0 ; j < (n-i-1); j++){
            if ( normal_is_greater(arr[j], arr[j+1]) )
            {
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}

int special_is_greater(int a, int b){
    if (a>=0 && b <0)  {
        return 0;
    } else if ( a<0 && b >=0)  {
        return 1;
    } else if ( a<0 && b <0)  {
        return a < b;
    } 
    else
        return a > b;
}

void buble_using_special_comparer(int arr[], int n)
{   // copy-pasted from 'plain_buble', but substitute a single row.
    int i,j;
    for (i=0; i< n; i++) {
        for (j = 0 ; j < (n-i-1); j++){
            if (  special_is_greater(arr[j], arr[j+1]) )  // <== yes, here 
            {
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}


int main() 
{ 
    int arr[] = {1 ,-1 ,-3 , -2, 7, 5, 11, 6 }; 
    int n = sizeof(arr)/sizeof(arr[0]); 

    plain_buble(arr,  n);
    for (int i = 0; i < n; i++) 
    {
        printf("%d ", arr[i]);
    }
    printf("\n"); 

    buble_using_special_comparer(arr,  n);
    for (int i = 0; i < n; i++) 
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
  
    return 0; 
} 

Result:

-3 -2 -1 1 5 6 7 11 
1 5 6 7 11 -1 -2 -3 

As long as we have a 'plain_buble' sort function, we can modify a bit to turn it into 'the sort we want'.

But the above sample is still not cool, because plain_buble and buble_using_special_comparer are almost the same.

We can use 'pointer of function' to do the magic. Like:

#include  <stdio.h> 
#include  <string.h>

typedef int (* CompareFunc)(int a, int b);

void buble_sort(int arr[], int n, CompareFunc is_greater)
{   // as the name says, this is a 'plain buble sort'
    int i,j;
    for (i=0; i< n; i++) {
        for (j = 0 ; j < (n-i-1); j++){
            if (is_greater(arr[j], arr[j+1]) )
            {
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}

int normal_is_greater(int a, int b){
    return a > b;
}


int special_is_greater(int a, int b){
    if (a>=0 && b <0)  {
        return 0;
    } else if ( a<0 && b >=0)  {
        return 1;
    } else if ( a<0 && b <0)  {
        return a < b;
    }
    else
        return a > b;
}


int main() 
{ 
    int arr[] = {1 ,-1 ,-3 , -2, 7, 5, 11, 6 }; 
    int n = sizeof(arr)/sizeof(arr[0]); 

    buble_sort(arr,  n,  normal_is_greater);
    for (int i = 0; i < n; i++) 
    {
        printf("%d ", arr[i]);
    }
    printf("\n"); 

    buble_sort(arr,  n, special_is_greater);
    for (int i = 0; i < n; i++) 
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
  
    return 0; 
} 

grizzlybears
  • 492
  • 2
  • 9
-2

First,a part of your code is this

int arr[] = {1 ,-1 ,-3 , -2, 7, 5, 11, 6 };

but,the output you want is

1 2 3 6 11 -1 -5 -7

You maybe make some mistakes : there is no -7 in the arr

I think the code below will solve your problem

#include <cstring>
#include <iostream>
using namespace std; 
  
void segregateElements(int arr[], int n) 
{ 
    int temp[n]; 
    int j = 0; // index of temp 
    for (int i = 0; i < n ; i++) 
        if (arr[i] >= 0 ) 
            temp[j++] = arr[i]; 
    if (j == 0 || j == 1) 
        return; 
    for(int i = 0;i < j;i++){
        for (int k = 0;k < j - 1;k++){
            if (temp[k+1]<temp[k]){
                int tg = temp[k+1];
                temp[k+1] = temp[k];
                temp[k] = tg;
            }
        }
    }
    for (int i = j;i < n;i++){
        for (int k = j;k < n - 1;k++){
            if (temp[k+1]<temp[k]){
                int tg = temp[k+1];
                temp[k+1] = temp[k];
                temp[k] = tg;
            }
        }
    }  

    for (int i = 0 ; i < n ; i++) 
        if (arr[i] < 0) 
            temp[j++] = arr[i]; 
  
    memcpy(arr, temp, sizeof(temp)); 
} 
  
int main() 
{ 
    int arr[] = {1 ,-1 ,-3 , -2, 7, 5, 11, 6 }; 
    int n = sizeof(arr)/sizeof(arr[0]); 
  
    segregateElements(arr, n); 
  
    for (int i = 0; i < n; i++) 
        cout << arr[i] << " "; 
    cout <<endl;
    return 0; 
} 
xxxxxxxb
  • 14
  • 2
  • First part of the answer addresses what is clearly an irrelevant typo. Second part is a code-only answer claiming you "think" it solves the problem but without explaining how or why. It does not solve the issue, which clearly requires the negatives to also be sorted. And it is poor style to chuck a sorting routine into a function that is intended only to partition a data set. Please edit your answer and elaborate on the solution. – paddy Jul 22 '22 at 03:59
  • 1
    `int temp[n];` -- This deserves a downvote. This is not valid C++. – PaulMcKenzie Jul 22 '22 at 04:01
  • Thanks a lot, this is what I expected! Sorry for output mistake, I mistaken it with other exercise. Anyways, I think this is the solution for me right now, hopefully, when I reach the algorithms it will get better! – berries Jul 22 '22 at 04:02
  • But what's wrong with this answer guys, I think this already solved the problem? – berries Jul 22 '22 at 04:03
  • @berries Others will do a search on StackOverflow for your title. Then they will get to this answer and see it will not even compile using a standard C++ compiler. The answer is flawed. Your question isn't going to be viewed in a vacuum. – PaulMcKenzie Jul 22 '22 at 04:05
  • Sorry guys, my stupid rookie question may confuse others, thanks for your feedback, I'd better delete it and reconsider my course, also, it stressed me out. – berries Jul 22 '22 at 04:09
  • 1
    [Doesn't compile](https://godbolt.org/z/nfz3xacPP). Now if you use the proper headers, it [still doesn't compile](https://godbolt.org/z/8EY4vKTsz). – PaulMcKenzie Jul 22 '22 at 04:13
  • sorry, you are correct, I corrected my code to make it look more spec – xxxxxxxb Jul 22 '22 at 04:21
  • 1
    @berries don't be discouraged by terse and critical feedback, nor the steep learning curve of programming. This is part of the learning process and it basically never ends. I've been coding for almost 35 years and I still get smashed all the time on Stack Overflow by other more experienced people, whether it's about a mistake I made, or a knowledge gap I have, or sometimes just a difference in style. ;) – paddy Jul 22 '22 at 04:37
  • @PaulMcKenzie I agree. Suggesting using non-standard extensions for a problem like this is not very good. I added an alternative solution using only standard C++. – Ted Lyngmo Jul 22 '22 at 05:41