Partitioning and sorting even and odd numbers within an arrayAsc and desc array sort methodsDynamic array...
What is "super" in superphosphate?
Tabularx with hline and overrightarrow vertical spacing
Vegetarian dishes on Russian trains (European part)
Did Wernher von Braun really have a "Saturn V painted as the V2"?
Does git delete empty folders?
How best to join tables, which have different lengths on the same column values which exist in both tables?
iPad or iPhone doesn't charge until unlocked?
Why is su world executable?
How to detect a failed AES256 decryption programmatically?
How do we test and determine if a USB cable+connector is version 2, 3.0 or 3.1?
From France west coast to Portugal via ship?
Can others monetize my project with GPLv3?
Are unaudited server logs admissible in a court of law?
Have made several mistakes during the course of my PhD. Can't help but feel resentment. Can I get some advice about how to move forward?
Check disk usage of files returned with spaces
Starships without computers?
What happened after the end of the Truman Show?
Saying something to a foreign coworker who uses "you people"
Is it alright to say good afternoon Sirs and Madams in a panel interview?
Designing a prison for a telekinetic race
Levenshtein Neighbours
Can sulfuric acid itself be electrolysed?
Why don't modern jet engines use forced exhaust mixing?
What are these protruding elements from SU-27's tail?
Partitioning and sorting even and odd numbers within an array
Asc and desc array sort methodsDynamic array sorting and storing programConstructing an odd-even mergesort sorting networkUVA #10258 - Contest ScoreboardPrint a String's even and odd indexesSplit linked list into odd and evenArray PartitioningOdd Even SubarraysSorting an array of numbers by descending frequency
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}
$begingroup$
I solved a problem where it was told to sort an array of numbers such that the even numbers are kept first and the odd numbers should follow. Moreover, the even numbers must be sorted in ascending order among them and the odd numbers as well. Only arrays can be used. My code is as follows , which works fine but it seems bit long to me. I wanted to know if there is anything I can do to shorten it and make it more readable.
#include <stdio.h>
int main(void)
{
int n,i,k,p,j,temp;
scanf("%d",&n);
int arr[n],arr_even[n],arr_odd[n];
k=0,p=0;
for(i=0;i<n;i++){
scanf("%d",&arr[i]);
if(arr[i]%2==0) arr_even[k++]=arr[i];
else arr_odd[p++]=arr[i];
}
for(i=0;i<k;i++){
for(j=0;j<=i;j++){
if(arr_even[j]>arr_even[i]){
temp=arr_even[i],arr_even[i]=arr_even[j],arr_even[j]=temp;
}
}
}
for(i=0;i<p;i++){
for(j=0;j<=i;j++){
if(arr_odd[j]>arr_odd[i]){
temp=arr_odd[i],arr_odd[i]=arr_odd[j],arr_odd[j]=temp;
}
}
}
p=0;
for(i=0;i<n;i++)
{
if(k) arr[i]=arr_even[i],k--;
else arr[i]=arr_odd[p++];
}
for(i=0;i<n;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
Input:
10
0 5 1 2 3 4 6 12 10 9
Output:
0 2 4 6 10 12 1 3 5 9
c array sorting
$endgroup$
add a comment |
$begingroup$
I solved a problem where it was told to sort an array of numbers such that the even numbers are kept first and the odd numbers should follow. Moreover, the even numbers must be sorted in ascending order among them and the odd numbers as well. Only arrays can be used. My code is as follows , which works fine but it seems bit long to me. I wanted to know if there is anything I can do to shorten it and make it more readable.
#include <stdio.h>
int main(void)
{
int n,i,k,p,j,temp;
scanf("%d",&n);
int arr[n],arr_even[n],arr_odd[n];
k=0,p=0;
for(i=0;i<n;i++){
scanf("%d",&arr[i]);
if(arr[i]%2==0) arr_even[k++]=arr[i];
else arr_odd[p++]=arr[i];
}
for(i=0;i<k;i++){
for(j=0;j<=i;j++){
if(arr_even[j]>arr_even[i]){
temp=arr_even[i],arr_even[i]=arr_even[j],arr_even[j]=temp;
}
}
}
for(i=0;i<p;i++){
for(j=0;j<=i;j++){
if(arr_odd[j]>arr_odd[i]){
temp=arr_odd[i],arr_odd[i]=arr_odd[j],arr_odd[j]=temp;
}
}
}
p=0;
for(i=0;i<n;i++)
{
if(k) arr[i]=arr_even[i],k--;
else arr[i]=arr_odd[p++];
}
for(i=0;i<n;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
Input:
10
0 5 1 2 3 4 6 12 10 9
Output:
0 2 4 6 10 12 1 3 5 9
c array sorting
$endgroup$
add a comment |
$begingroup$
I solved a problem where it was told to sort an array of numbers such that the even numbers are kept first and the odd numbers should follow. Moreover, the even numbers must be sorted in ascending order among them and the odd numbers as well. Only arrays can be used. My code is as follows , which works fine but it seems bit long to me. I wanted to know if there is anything I can do to shorten it and make it more readable.
#include <stdio.h>
int main(void)
{
int n,i,k,p,j,temp;
scanf("%d",&n);
int arr[n],arr_even[n],arr_odd[n];
k=0,p=0;
for(i=0;i<n;i++){
scanf("%d",&arr[i]);
if(arr[i]%2==0) arr_even[k++]=arr[i];
else arr_odd[p++]=arr[i];
}
for(i=0;i<k;i++){
for(j=0;j<=i;j++){
if(arr_even[j]>arr_even[i]){
temp=arr_even[i],arr_even[i]=arr_even[j],arr_even[j]=temp;
}
}
}
for(i=0;i<p;i++){
for(j=0;j<=i;j++){
if(arr_odd[j]>arr_odd[i]){
temp=arr_odd[i],arr_odd[i]=arr_odd[j],arr_odd[j]=temp;
}
}
}
p=0;
for(i=0;i<n;i++)
{
if(k) arr[i]=arr_even[i],k--;
else arr[i]=arr_odd[p++];
}
for(i=0;i<n;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
Input:
10
0 5 1 2 3 4 6 12 10 9
Output:
0 2 4 6 10 12 1 3 5 9
c array sorting
$endgroup$
I solved a problem where it was told to sort an array of numbers such that the even numbers are kept first and the odd numbers should follow. Moreover, the even numbers must be sorted in ascending order among them and the odd numbers as well. Only arrays can be used. My code is as follows , which works fine but it seems bit long to me. I wanted to know if there is anything I can do to shorten it and make it more readable.
#include <stdio.h>
int main(void)
{
int n,i,k,p,j,temp;
scanf("%d",&n);
int arr[n],arr_even[n],arr_odd[n];
k=0,p=0;
for(i=0;i<n;i++){
scanf("%d",&arr[i]);
if(arr[i]%2==0) arr_even[k++]=arr[i];
else arr_odd[p++]=arr[i];
}
for(i=0;i<k;i++){
for(j=0;j<=i;j++){
if(arr_even[j]>arr_even[i]){
temp=arr_even[i],arr_even[i]=arr_even[j],arr_even[j]=temp;
}
}
}
for(i=0;i<p;i++){
for(j=0;j<=i;j++){
if(arr_odd[j]>arr_odd[i]){
temp=arr_odd[i],arr_odd[i]=arr_odd[j],arr_odd[j]=temp;
}
}
}
p=0;
for(i=0;i<n;i++)
{
if(k) arr[i]=arr_even[i],k--;
else arr[i]=arr_odd[p++];
}
for(i=0;i<n;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
Input:
10
0 5 1 2 3 4 6 12 10 9
Output:
0 2 4 6 10 12 1 3 5 9
c array sorting
c array sorting
edited Aug 15 at 18:28
200_success
135k21 gold badges173 silver badges443 bronze badges
135k21 gold badges173 silver badges443 bronze badges
asked Aug 15 at 17:45
Nehal SameeNehal Samee
1586 bronze badges
1586 bronze badges
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
$begingroup$
Your code is quite complicated. The C standard library provides all the ingredients you need to sort an array. You just need to define a comparison function. All the rest is done by the qsort
function from stdlib.h
.
The comparison function should look like:
static int even_first(const void *a, const void *b) {
int left = *(const int *)a;
int right = *(const int *)b;
int res = (left % 2 != 0) - (right % 2 != 0);
if (res == 0)
res = (left > right) - (left < right);
return res;
}
The expressions of the form cond1 - cond2
may look strange at first, but they are commonly used in C code in comparison functions like this one.
The benefit over a naïve left - right
is that no integer overflow can happen. Integer overflow is a common source of undefined behavior.
To make the code more readable, it's also possible to extract the basic integer comparison into a separate function:
static int compare(int a, int b) {
return a < b ? -1 : a > b ? +1 : 0;
// alternatively: return (a > b) - (a < b);
// alternatively: return a < b ? -1 : a > b;
}
Then, the comparison function becomes:
static int even_first(const void *a, const void *b) {
int left = *(const int *)a;
int right = *(const int *)b;
int res = compare(left % 2 != 0, right % 2 != 0);
if (res == 0)
res = compare(left, right);
return res;
}
This form is much less of a brain twister than the above variant.
$endgroup$
add a comment |
$begingroup$
Firstly, we should separate the sorting from the reading of inputs and writing of outputs. We can create a function sort_evens_first()
- that's the foundation of writing re-usable code. An advantage (even in this small program) is that a separable function can more easily be tested - no need for an external script to run many instances of the program with different inputs, making tests run much faster; also it makes it easier to distinguish bugs in the I/O from bugs in the algorithm
Secondly, the Standard Library provides us with qsort()
to save us having to re-implement sort every time (and it's usually more efficient than the bubble sort implemented here). We need to give it a comparator function as follows:
- if one element is even and the other is odd, the even number sorts before the odd one,
- else, the numerically smaller one is lower.
That looks like:
int compare_evens_first(const void *va, const void *vb)
{
const int *a = va;
const int *b = vb;
if (*a % 2 != *b % 2)
return (*a % 2) - (*b % 2);
// else both odd, or both even
// return *a - *b might overflow, so avoid that
return (*a > *b) - (*a < *b);
}
Then we can simply use it:
#include <stdlib.h>
void sort_evens_first(int *array, size_t count)
{
qsort(array, count, sizeof *array, compare_evens_first);
}
N.B. I've not had time to test this code; bugs may be lurking.
Additional problems with the supporting code
When reading input with scanf()
and family, it is essential to confirm the return value before using any of the results.
It's less important to check the result of printf()
as failure there is less likely to lead to bad outcomes, but it's still worth considering so that we can return EXIT_FAILURE
if the output wasn't successfully written (it might not be obvious to the user if directed to a file or pipeline, for example).
$endgroup$
$begingroup$
@Roland - fixed; thanks!
$endgroup$
– Toby Speight
2 days ago
1
$begingroup$
I'd tend to writeint const * const a = va;
(note the twoconst
s). I'd also be tempted to writeconst int parity = (*a % 2) - (*b % 2); if (parity != 0) return parity;
$endgroup$
– Martin Bonner
2 days ago
$begingroup$
The answer from Roland actually extracts the int from the void pointer once, and then uses that - I prefer that too.
$endgroup$
– Martin Bonner
2 days ago
3
$begingroup$
@Martin - I feel that the conversion by assignment is slightly safer than casting the pointers, so that one is just two different preferences. There's arguments for both, and they could even be combined if you don't mind two more temporaries.
$endgroup$
– Toby Speight
2 days ago
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f226196%2fpartitioning-and-sorting-even-and-odd-numbers-within-an-array%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
Your code is quite complicated. The C standard library provides all the ingredients you need to sort an array. You just need to define a comparison function. All the rest is done by the qsort
function from stdlib.h
.
The comparison function should look like:
static int even_first(const void *a, const void *b) {
int left = *(const int *)a;
int right = *(const int *)b;
int res = (left % 2 != 0) - (right % 2 != 0);
if (res == 0)
res = (left > right) - (left < right);
return res;
}
The expressions of the form cond1 - cond2
may look strange at first, but they are commonly used in C code in comparison functions like this one.
The benefit over a naïve left - right
is that no integer overflow can happen. Integer overflow is a common source of undefined behavior.
To make the code more readable, it's also possible to extract the basic integer comparison into a separate function:
static int compare(int a, int b) {
return a < b ? -1 : a > b ? +1 : 0;
// alternatively: return (a > b) - (a < b);
// alternatively: return a < b ? -1 : a > b;
}
Then, the comparison function becomes:
static int even_first(const void *a, const void *b) {
int left = *(const int *)a;
int right = *(const int *)b;
int res = compare(left % 2 != 0, right % 2 != 0);
if (res == 0)
res = compare(left, right);
return res;
}
This form is much less of a brain twister than the above variant.
$endgroup$
add a comment |
$begingroup$
Your code is quite complicated. The C standard library provides all the ingredients you need to sort an array. You just need to define a comparison function. All the rest is done by the qsort
function from stdlib.h
.
The comparison function should look like:
static int even_first(const void *a, const void *b) {
int left = *(const int *)a;
int right = *(const int *)b;
int res = (left % 2 != 0) - (right % 2 != 0);
if (res == 0)
res = (left > right) - (left < right);
return res;
}
The expressions of the form cond1 - cond2
may look strange at first, but they are commonly used in C code in comparison functions like this one.
The benefit over a naïve left - right
is that no integer overflow can happen. Integer overflow is a common source of undefined behavior.
To make the code more readable, it's also possible to extract the basic integer comparison into a separate function:
static int compare(int a, int b) {
return a < b ? -1 : a > b ? +1 : 0;
// alternatively: return (a > b) - (a < b);
// alternatively: return a < b ? -1 : a > b;
}
Then, the comparison function becomes:
static int even_first(const void *a, const void *b) {
int left = *(const int *)a;
int right = *(const int *)b;
int res = compare(left % 2 != 0, right % 2 != 0);
if (res == 0)
res = compare(left, right);
return res;
}
This form is much less of a brain twister than the above variant.
$endgroup$
add a comment |
$begingroup$
Your code is quite complicated. The C standard library provides all the ingredients you need to sort an array. You just need to define a comparison function. All the rest is done by the qsort
function from stdlib.h
.
The comparison function should look like:
static int even_first(const void *a, const void *b) {
int left = *(const int *)a;
int right = *(const int *)b;
int res = (left % 2 != 0) - (right % 2 != 0);
if (res == 0)
res = (left > right) - (left < right);
return res;
}
The expressions of the form cond1 - cond2
may look strange at first, but they are commonly used in C code in comparison functions like this one.
The benefit over a naïve left - right
is that no integer overflow can happen. Integer overflow is a common source of undefined behavior.
To make the code more readable, it's also possible to extract the basic integer comparison into a separate function:
static int compare(int a, int b) {
return a < b ? -1 : a > b ? +1 : 0;
// alternatively: return (a > b) - (a < b);
// alternatively: return a < b ? -1 : a > b;
}
Then, the comparison function becomes:
static int even_first(const void *a, const void *b) {
int left = *(const int *)a;
int right = *(const int *)b;
int res = compare(left % 2 != 0, right % 2 != 0);
if (res == 0)
res = compare(left, right);
return res;
}
This form is much less of a brain twister than the above variant.
$endgroup$
Your code is quite complicated. The C standard library provides all the ingredients you need to sort an array. You just need to define a comparison function. All the rest is done by the qsort
function from stdlib.h
.
The comparison function should look like:
static int even_first(const void *a, const void *b) {
int left = *(const int *)a;
int right = *(const int *)b;
int res = (left % 2 != 0) - (right % 2 != 0);
if (res == 0)
res = (left > right) - (left < right);
return res;
}
The expressions of the form cond1 - cond2
may look strange at first, but they are commonly used in C code in comparison functions like this one.
The benefit over a naïve left - right
is that no integer overflow can happen. Integer overflow is a common source of undefined behavior.
To make the code more readable, it's also possible to extract the basic integer comparison into a separate function:
static int compare(int a, int b) {
return a < b ? -1 : a > b ? +1 : 0;
// alternatively: return (a > b) - (a < b);
// alternatively: return a < b ? -1 : a > b;
}
Then, the comparison function becomes:
static int even_first(const void *a, const void *b) {
int left = *(const int *)a;
int right = *(const int *)b;
int res = compare(left % 2 != 0, right % 2 != 0);
if (res == 0)
res = compare(left, right);
return res;
}
This form is much less of a brain twister than the above variant.
edited 2 days ago
Toby Speight
31.3k7 gold badges45 silver badges135 bronze badges
31.3k7 gold badges45 silver badges135 bronze badges
answered Aug 15 at 20:32
Roland IlligRoland Illig
14.8k2 gold badges23 silver badges56 bronze badges
14.8k2 gold badges23 silver badges56 bronze badges
add a comment |
add a comment |
$begingroup$
Firstly, we should separate the sorting from the reading of inputs and writing of outputs. We can create a function sort_evens_first()
- that's the foundation of writing re-usable code. An advantage (even in this small program) is that a separable function can more easily be tested - no need for an external script to run many instances of the program with different inputs, making tests run much faster; also it makes it easier to distinguish bugs in the I/O from bugs in the algorithm
Secondly, the Standard Library provides us with qsort()
to save us having to re-implement sort every time (and it's usually more efficient than the bubble sort implemented here). We need to give it a comparator function as follows:
- if one element is even and the other is odd, the even number sorts before the odd one,
- else, the numerically smaller one is lower.
That looks like:
int compare_evens_first(const void *va, const void *vb)
{
const int *a = va;
const int *b = vb;
if (*a % 2 != *b % 2)
return (*a % 2) - (*b % 2);
// else both odd, or both even
// return *a - *b might overflow, so avoid that
return (*a > *b) - (*a < *b);
}
Then we can simply use it:
#include <stdlib.h>
void sort_evens_first(int *array, size_t count)
{
qsort(array, count, sizeof *array, compare_evens_first);
}
N.B. I've not had time to test this code; bugs may be lurking.
Additional problems with the supporting code
When reading input with scanf()
and family, it is essential to confirm the return value before using any of the results.
It's less important to check the result of printf()
as failure there is less likely to lead to bad outcomes, but it's still worth considering so that we can return EXIT_FAILURE
if the output wasn't successfully written (it might not be obvious to the user if directed to a file or pipeline, for example).
$endgroup$
$begingroup$
@Roland - fixed; thanks!
$endgroup$
– Toby Speight
2 days ago
1
$begingroup$
I'd tend to writeint const * const a = va;
(note the twoconst
s). I'd also be tempted to writeconst int parity = (*a % 2) - (*b % 2); if (parity != 0) return parity;
$endgroup$
– Martin Bonner
2 days ago
$begingroup$
The answer from Roland actually extracts the int from the void pointer once, and then uses that - I prefer that too.
$endgroup$
– Martin Bonner
2 days ago
3
$begingroup$
@Martin - I feel that the conversion by assignment is slightly safer than casting the pointers, so that one is just two different preferences. There's arguments for both, and they could even be combined if you don't mind two more temporaries.
$endgroup$
– Toby Speight
2 days ago
add a comment |
$begingroup$
Firstly, we should separate the sorting from the reading of inputs and writing of outputs. We can create a function sort_evens_first()
- that's the foundation of writing re-usable code. An advantage (even in this small program) is that a separable function can more easily be tested - no need for an external script to run many instances of the program with different inputs, making tests run much faster; also it makes it easier to distinguish bugs in the I/O from bugs in the algorithm
Secondly, the Standard Library provides us with qsort()
to save us having to re-implement sort every time (and it's usually more efficient than the bubble sort implemented here). We need to give it a comparator function as follows:
- if one element is even and the other is odd, the even number sorts before the odd one,
- else, the numerically smaller one is lower.
That looks like:
int compare_evens_first(const void *va, const void *vb)
{
const int *a = va;
const int *b = vb;
if (*a % 2 != *b % 2)
return (*a % 2) - (*b % 2);
// else both odd, or both even
// return *a - *b might overflow, so avoid that
return (*a > *b) - (*a < *b);
}
Then we can simply use it:
#include <stdlib.h>
void sort_evens_first(int *array, size_t count)
{
qsort(array, count, sizeof *array, compare_evens_first);
}
N.B. I've not had time to test this code; bugs may be lurking.
Additional problems with the supporting code
When reading input with scanf()
and family, it is essential to confirm the return value before using any of the results.
It's less important to check the result of printf()
as failure there is less likely to lead to bad outcomes, but it's still worth considering so that we can return EXIT_FAILURE
if the output wasn't successfully written (it might not be obvious to the user if directed to a file or pipeline, for example).
$endgroup$
$begingroup$
@Roland - fixed; thanks!
$endgroup$
– Toby Speight
2 days ago
1
$begingroup$
I'd tend to writeint const * const a = va;
(note the twoconst
s). I'd also be tempted to writeconst int parity = (*a % 2) - (*b % 2); if (parity != 0) return parity;
$endgroup$
– Martin Bonner
2 days ago
$begingroup$
The answer from Roland actually extracts the int from the void pointer once, and then uses that - I prefer that too.
$endgroup$
– Martin Bonner
2 days ago
3
$begingroup$
@Martin - I feel that the conversion by assignment is slightly safer than casting the pointers, so that one is just two different preferences. There's arguments for both, and they could even be combined if you don't mind two more temporaries.
$endgroup$
– Toby Speight
2 days ago
add a comment |
$begingroup$
Firstly, we should separate the sorting from the reading of inputs and writing of outputs. We can create a function sort_evens_first()
- that's the foundation of writing re-usable code. An advantage (even in this small program) is that a separable function can more easily be tested - no need for an external script to run many instances of the program with different inputs, making tests run much faster; also it makes it easier to distinguish bugs in the I/O from bugs in the algorithm
Secondly, the Standard Library provides us with qsort()
to save us having to re-implement sort every time (and it's usually more efficient than the bubble sort implemented here). We need to give it a comparator function as follows:
- if one element is even and the other is odd, the even number sorts before the odd one,
- else, the numerically smaller one is lower.
That looks like:
int compare_evens_first(const void *va, const void *vb)
{
const int *a = va;
const int *b = vb;
if (*a % 2 != *b % 2)
return (*a % 2) - (*b % 2);
// else both odd, or both even
// return *a - *b might overflow, so avoid that
return (*a > *b) - (*a < *b);
}
Then we can simply use it:
#include <stdlib.h>
void sort_evens_first(int *array, size_t count)
{
qsort(array, count, sizeof *array, compare_evens_first);
}
N.B. I've not had time to test this code; bugs may be lurking.
Additional problems with the supporting code
When reading input with scanf()
and family, it is essential to confirm the return value before using any of the results.
It's less important to check the result of printf()
as failure there is less likely to lead to bad outcomes, but it's still worth considering so that we can return EXIT_FAILURE
if the output wasn't successfully written (it might not be obvious to the user if directed to a file or pipeline, for example).
$endgroup$
Firstly, we should separate the sorting from the reading of inputs and writing of outputs. We can create a function sort_evens_first()
- that's the foundation of writing re-usable code. An advantage (even in this small program) is that a separable function can more easily be tested - no need for an external script to run many instances of the program with different inputs, making tests run much faster; also it makes it easier to distinguish bugs in the I/O from bugs in the algorithm
Secondly, the Standard Library provides us with qsort()
to save us having to re-implement sort every time (and it's usually more efficient than the bubble sort implemented here). We need to give it a comparator function as follows:
- if one element is even and the other is odd, the even number sorts before the odd one,
- else, the numerically smaller one is lower.
That looks like:
int compare_evens_first(const void *va, const void *vb)
{
const int *a = va;
const int *b = vb;
if (*a % 2 != *b % 2)
return (*a % 2) - (*b % 2);
// else both odd, or both even
// return *a - *b might overflow, so avoid that
return (*a > *b) - (*a < *b);
}
Then we can simply use it:
#include <stdlib.h>
void sort_evens_first(int *array, size_t count)
{
qsort(array, count, sizeof *array, compare_evens_first);
}
N.B. I've not had time to test this code; bugs may be lurking.
Additional problems with the supporting code
When reading input with scanf()
and family, it is essential to confirm the return value before using any of the results.
It's less important to check the result of printf()
as failure there is less likely to lead to bad outcomes, but it's still worth considering so that we can return EXIT_FAILURE
if the output wasn't successfully written (it might not be obvious to the user if directed to a file or pipeline, for example).
edited 2 days ago
answered Aug 15 at 18:33
Toby SpeightToby Speight
31.3k7 gold badges45 silver badges135 bronze badges
31.3k7 gold badges45 silver badges135 bronze badges
$begingroup$
@Roland - fixed; thanks!
$endgroup$
– Toby Speight
2 days ago
1
$begingroup$
I'd tend to writeint const * const a = va;
(note the twoconst
s). I'd also be tempted to writeconst int parity = (*a % 2) - (*b % 2); if (parity != 0) return parity;
$endgroup$
– Martin Bonner
2 days ago
$begingroup$
The answer from Roland actually extracts the int from the void pointer once, and then uses that - I prefer that too.
$endgroup$
– Martin Bonner
2 days ago
3
$begingroup$
@Martin - I feel that the conversion by assignment is slightly safer than casting the pointers, so that one is just two different preferences. There's arguments for both, and they could even be combined if you don't mind two more temporaries.
$endgroup$
– Toby Speight
2 days ago
add a comment |
$begingroup$
@Roland - fixed; thanks!
$endgroup$
– Toby Speight
2 days ago
1
$begingroup$
I'd tend to writeint const * const a = va;
(note the twoconst
s). I'd also be tempted to writeconst int parity = (*a % 2) - (*b % 2); if (parity != 0) return parity;
$endgroup$
– Martin Bonner
2 days ago
$begingroup$
The answer from Roland actually extracts the int from the void pointer once, and then uses that - I prefer that too.
$endgroup$
– Martin Bonner
2 days ago
3
$begingroup$
@Martin - I feel that the conversion by assignment is slightly safer than casting the pointers, so that one is just two different preferences. There's arguments for both, and they could even be combined if you don't mind two more temporaries.
$endgroup$
– Toby Speight
2 days ago
$begingroup$
@Roland - fixed; thanks!
$endgroup$
– Toby Speight
2 days ago
$begingroup$
@Roland - fixed; thanks!
$endgroup$
– Toby Speight
2 days ago
1
1
$begingroup$
I'd tend to write
int const * const a = va;
(note the two const
s). I'd also be tempted to write const int parity = (*a % 2) - (*b % 2); if (parity != 0) return parity;
$endgroup$
– Martin Bonner
2 days ago
$begingroup$
I'd tend to write
int const * const a = va;
(note the two const
s). I'd also be tempted to write const int parity = (*a % 2) - (*b % 2); if (parity != 0) return parity;
$endgroup$
– Martin Bonner
2 days ago
$begingroup$
The answer from Roland actually extracts the int from the void pointer once, and then uses that - I prefer that too.
$endgroup$
– Martin Bonner
2 days ago
$begingroup$
The answer from Roland actually extracts the int from the void pointer once, and then uses that - I prefer that too.
$endgroup$
– Martin Bonner
2 days ago
3
3
$begingroup$
@Martin - I feel that the conversion by assignment is slightly safer than casting the pointers, so that one is just two different preferences. There's arguments for both, and they could even be combined if you don't mind two more temporaries.
$endgroup$
– Toby Speight
2 days ago
$begingroup$
@Martin - I feel that the conversion by assignment is slightly safer than casting the pointers, so that one is just two different preferences. There's arguments for both, and they could even be combined if you don't mind two more temporaries.
$endgroup$
– Toby Speight
2 days ago
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f226196%2fpartitioning-and-sorting-even-and-odd-numbers-within-an-array%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown