To sort an array in required manner - c

I need to sort the elements in the odd positions in the descending order and elements in the even position in ascending order. Here is my code, I'm unable to break the first loop.
#include<stdio.h>
int main()
{
int n, t;
printf("Enter the size of the array\n");
scanf("%d", &n);
int i, a[n];
if ((n > 20) || (n <= 0))
printf("Invalid Size");
else
{
printf("Enter the values\n");
for (i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
for (i = 0; i < n; i + 2)
{
if (a[i] > a[i + 2])
{
t = a[i];
a[i] = a[i + 2];
a[i + 2] = t;
}
}
for (i = 1; i < n; i + 2)
{
if (a[i] < a[i + 2])
{
t = a[i];
a[i] = a[i + 2];
a[i + 2] = t;
}
}
for (i = 0; i < n; i++)
{
printf("%d\n", a[i]);
}
}
}

For starters according to the C Standard the function main without parameters shall be declared like
int main( void )
There is no great sense to declare the variable n as having the type int that after that to check whether its value is less than zero. It is much better to declare it as having the type size_t.
And the array should be declared after the check
if ((n > 20) || (n <= 0))
printf("Invalid Size");
else
{
int a[n];
//...
In loops like this
for (i = 0; i < n; i + 2)
the variable i is not increased. It is obvious that you mean i += 2.
And the loops only moves the first minimum even and the first maximum odd elements to the end of the array. You need additional loops that will do the same operation for other elements of the array. That is the implementation of the bubble sort algorithm is incorrect.
Here is a demonstrative program that shows how the array can be sorted according to the requirements for even and odd elements of the array.
#include <stdio.h>
#define N 20
int main(void)
{
int a[N] = { 18, 1, 16, 3, 14, 5, 12, 7, 10, 9, 8, 11, 6, 13, 4, 15, 2, 17, 0, 19 };
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
for ( size_t n = N, last; !( n < 3 ); n = last )
{
for ( size_t i = last = 2; i < n; i++ )
{
if ( ( i % 2 == 0 && a[i] < a[i - 2] ) ||
( i % 2 == 1 && a[i - 2] < a[i] ) )
{
int tmp = a[i];
a[i] = a[i - 2];
a[i - 2] = tmp;
last = i;
}
}
}
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
return 0;
}
The program output is
18 1 16 3 14 5 12 7 10 9 8 11 6 13 4 15 2 17 0 19
0 19 2 17 4 15 6 13 8 11 10 9 12 7 14 5 16 3 18 1

The most obvious problem is that your for never ends because i is never actually updated. The i+2 in for (i = 0; i < n; i + 2) does not update i which keeps its initia value forever.
Try something like for (i = 0; i < n; i=i+2) instead.
A second problem is that you are not really performing a sorting.
I guess that you are trying to implement some sort of bubble sort.
It sorts using comparison. It is impossible to sort an array using less than n logn operation (when sorting using comparison). You are sorting the array in linear time and this should look as a red flag to you.
Try adding another for as follows:
for (i = 0; i < n; i+= 2)
for (j = i+2; j < n; j+= 2)
if (a[i] > a[j])
{
t = a[i];
a[i] = a[j];
a[j] = t;
}
and most importantly then read about why you need it.
And if you feel brave you can swap the intgers without using an intermediate variable t as follows (read more on the topic here: XOR swap):
if (a[i] > a[j])
{
a[i] = a[i]^a[j];
a[j] = a[j]^a[i];
a[i] = a[i]^a[j];
}
Hope it helps.

Related

dealing with dups in end of the array

This is the task I have got:
I need to write a function (not recursive) which has two parameters.
An array of integers.
An integer representing the size of the array.
The function will move the duplicates to an end of the array.
And will give the size of the different digits.
Example:
5 , 2 , 4 , 5 , 6 , 7 , 2, n = 7
we will get back 5 , 2 , 4 , 6 , 7 , 5 , 2 and 5
We must keep the original sort as it is (which means like in example 5 must)
It does not matter how we sort the duplicates ones but just keep the sort for the original array as it is)
The function has to print the number of different digits (like in example 5)
The the input range of numbers in array [-n,n]
I can only use 1 additional array for help.
It has to be O(n)
I tried it so many times and feel like am missing something. Would appreciate any advice/suggestions.
int moveDup(int* arr, int n)
{
int* C = (int*)calloc(n * 2 + 1, sizeof(int));
assert(C);
/*int* count = C + n;*/
int *D = arr[0];
int value = 0, count = 0;
for (int i = 0; i < n; i++)
{
value = arr[i];
if (C[value + n] == 0)
{
*D = arr[i];
D++;
count++;
}
C[value + n] = C[value + n] + 1;
}
while (1 < C[value + n])
{
*D = i;
D++;
C[value + n]--;
}
free(C);
return count;
}
This algorithm will produce the required results in O(n) arithmetic complexity:
Input is an array A with n elements indexed from A0 to An−1 inclusive. For each Ai, −n ≤ Ai ≤ n.
Create an array C that can be indexed from C−n to C+n, inclusive. Initialize C to all zeros.
Define a pointer D. Initialize D to point to A0.
For 0 ≤ i < n:
If CAi=0, copy Ai to where D points and advance D one element.
Increment CAi.
Set r to the number of elements D has been advanced from A0.
For −n ≤ i ≤ +n:
While 1 < CAi:
Copy i to where D points and advance D one element.
Decrement CAi.
Release C.
Return r. A contains the required values.
A sample implementation is:
#include <stdio.h>
#include <stdlib.h>
#define NumberOf(a) (sizeof (a) / sizeof *(a))
int moveDuplicates(int Array[], int n)
{
int *memory = calloc(2*n+1, sizeof *Array);
if (!memory)
{
fprintf(stderr, "Error, unable to allocate memory.\n");
exit(EXIT_FAILURE);
}
int *count = memory + n;
int *destination = Array;
for (int i = 0; i < n; ++i)
// Count each element. If it is unique, move it to the front.
if (!count[Array[i]]++)
*destination++ = Array[i];
// Record how many unique elements were found.
int result = destination - Array;
// Append duplicates to back.
for (int i = -n; i <= n; ++i)
while (0 < --count[i])
*destination++ = i;
free(memory);
return result;
}
int main(void)
{
int Array[] = { 5, 2, 4, 5, 6, 7, 2 };
printf("There are %d different numbers.\n",
moveDuplicates(Array, NumberOf(Array)));
for (int i = 0; i < NumberOf(Array); ++i)
printf(" %d", Array[i]);
printf("\n");
}
here is the right answer, figured it out by myself.
int moveDup(int* arr, int n)
{
int* seen_before = (int*)calloc(n * 2 + 1, sizeof(int));
assert(seen_before);
int val = 0, count = 0, flag = 1;
int j = 0;
for (int i = 0; i < n; i++)
{
val = arr[i];
if (seen_before[arr[i] + n] == 0)
{
seen_before[arr[i] + n]++;
count++;
continue;
}
else if (flag)
{
j = i + 1;
flag = 0;
}
while (j < n)
{
if (seen_before[arr[j] + n] == 0)
{
count++;
seen_before[arr[j] + n]++;
swap(&arr[i], &arr[j]);
j++;
if (j == n)
{
free(seen_before);
return count;
}
break;
}
/*break;*/
j++;
if (j == n)
{
free(seen_before);
return count;
}
}
}
}
second right answer
int* mem = (int*)calloc(2 * n + 1, sizeof * arr);
assert(mem);
int* count = mem + n;
int* dest = arr;
for (i = 0; i < n; ++i)
{
if (count[arr[i]]++ == 0)
{
*dest = arr[i];
*dest++;
}
}
res = dest - arr;
for (i = -n; i <= n; ++i)
{
while (0 < --count[i])
{
*dest++ = i;
}
}
free(mem);
return res;

reverse array in range in C

I have to solve it in C language. I have arrays with n integers. L and U are lower and upper bound. I have to reverse numbers in array which is in [L,U]. I tried it by this way, but in some cases the answer is wrong. What mist be changed in the code? Or is there any other logic to complete the task?
#include <stdio.h>
int main() {
int x, arr[100], n, l, u, a, temp, temp1;
scanf("%d%d%d", &n, &l, &u);
for (int i = 0; i < n; i++) {
scanf("%d", &x); // read elements of an array
arr[i] = x;
}
a = n / 2;
for (int i = 0; i < a; i++) {
for (int j = a; j < n; j++) {
if (arr[i] >= l && arr[i] <= u) {
if (arr[j] >=l && arr[j] < u) {
temp = arr[j];
temp1 = arr[i];
arr[i] = temp;
arr[j] = temp1;
}
}
}
}
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
}
sample input:
10(number of integers) -7(lower bound) 5(upper bound)
-10 -9 5 -2 -3 7 10 6 -8 -5
sample output:
-10 -9 -5 -3 -2 7 10 6 -8 5
my output:
-10 -9 -5 -2 -3 7 10 6 -8 5
There is an O(N) solution that does not require nesting of loops.
First, with the code as you as you have it, declare an additional array and some other helper variables that keeps track of what indices need to be swapped.
int left, right;
int swaplist[100] = {0};
int swapcount = 0;
Your can keep your initial intake loop exactly as you have it, but amended to append the index of the newly scanned value to the swaplist array if the value is between the lower and upper bounds.
for (int i = 0; i < n; i++) {
scanf("%d", &x); // read elements of an array
arr[i] = x;
if ((x >= l) && (x <= u)) {
swaplist[swapcount++] = i;
}
}
Then a single loop to iterate over "swaplist" and do the swaps against the original array.
left = 0;
right = swapcount-1;
while (left < right) {
int leftindex = table[left];
int rightindex = table[right];
int tmp = arr[leftindex];
arr[leftindex] = arr[rightindex];
arr[rightindex] = tmp;
left++; right--;
}
You made a valiant attempt. Your nested for() loops are appropriate for some kinds of sorting algorithms, but not for what seems to be the purpose of this task.
From the sample input and desired output, you really want to establish a 'bracket' at either end of the array, then shift both toward the centre, swapping elements whose value happens to satisfy low <= n <= high value. (In this case, -7 <= n <= 5).
Here's a solution:
#include <stdio.h>
int swap( int arr[], size_t l, size_t r ) { // conventional swap algorithm
int t = arr[l];
arr[l] = arr[r];
arr[r] = t;
return 1;
}
int main() {
int arr[] = { -10, -9, 5, -2, -3, 7, 10, 6, -8, -5, }; // your data
size_t i, sz = sizeof arr/sizeof arr[0];
for( i = 0; i < sz; i++ ) // showing original version
printf( "%d ", arr[i] );
putchar( '\n' );
#define inRange( x ) ( -7 <= arr[x] && arr[x] <= 5 ) // a good time for a macro
size_t L = 0, R = sz - 1; // 'L'eft and 'R'ight "brackets"
do {
while( L < R && !inRange( L ) ) L++; // scan from left to find a target
while( L < R && !inRange( R ) ) R--; // scan from right to find a target
} while( L < R && swap( arr, L, R ) && (L+=1) > 0 && (R-=1) > 0 );
for( i = 0; i < sz; i++ ) // showing results
printf( "%d ", arr[i] );
putchar( '\n' );
return 0;
}
-10 -9 5 -2 -3 7 10 6 -8 -5
-10 -9 -5 -3 -2 7 10 6 -8 5
If I have understood the assignment correctly you need to reverse elements of an array that satisfy some condition.
If so then these nested for loops
for (int i = 0; i < a; i++) {
for (int j = a; j < n; j++) {
if (arr[i] >= l && arr[i] <= u) {
if (arr[j] >=l && arr[j] < u) {
temp = arr[j];
temp1 = arr[i];
arr[i] = temp;
arr[j] = temp1;
}
}
}
}
do not make sense.
It is enough to use only one for loop as shown in the demonstration program below.
#include <stdio.h>
int main( void )
{
int a[] = { 1, 10, 2, 3, 20, 4, 30, 5, 40, 6, 7, 50, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
int l = 10, u = 50;
for (size_t i = 0, j = N; i < j; i++ )
{
while (i < j && !( l <= a[i] && a[i] <= u )) ++i;
if (i < j)
{
while (i < --j && !( l <= a[j] && a[j] <= u ));
if (i < j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}
}
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
}
The program output is
1 10 2 3 20 4 30 5 40 6 7 50 9
1 50 2 3 40 4 30 5 20 6 7 10 9
You could write a separate function as for example
#include <stdio.h>
void reverse_in_range( int a[], size_t n, int low, int upper )
{
for (size_t i = 0, j = n; i < j; )
{
while (i < j && !( low <= a[i] && a[i] <= upper )) ++i;
if (i < j)
{
while (i < --j && !( low <= a[j] && a[j] <= upper ));
if (i < j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
++i;
}
}
}
}
int main( void )
{
int a[] = { 1, 10, 2, 3, 20, 4, 30, 5, 40, 6, 7, 50, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
reverse_in_range( a, N, 10,50 );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
}
Thanks for everyone help. I read all of them, but I found another way to solve this problem. I will write it just in case. (some variable names are random, so in case of questions, comment).
#include <stdio.h>
int main() {
int x, main[100], n, l, u, a = 0, arr[100], temp, m = 0,f=0,c,d;
scanf("%d%d%d", &n, &l, &u);
for (int i = 0; i < n; i++) {
scanf("%d", &x); // read elements of an array
main[i] = x;
if (x >= l && x <= u) {
a++; //check if element is in range [l,u] and increasing a. later "a" will be used a length of the array "arr". this array cootains elements, which in in [u,l].
}
}
//add [u,l] elements in new array "arr"
for (int i = 0; i < n; i++) {
if (main[i] >= l && main[i] <= u) {
arr[m] = main[i];
m++; //index counter of "arr",
}
}
d=0;
for(int i=0;i<n;i++){
if(main[i]==arr[d]){
c=arr[a-d-1];
main[i]=c;
d++;
}
}
for(int i=0;i<n;i++){
printf("%d ",main[i]);
}
}
My best guess is that scanf is very annoying, on top of that, your format is ambiguous.
How will %d%d%d read 1234? Will it give you 12 3 and 4? 1 23 and 4? ...
try to do
scanf("%d %d %d" ...); // or
scanf("%d, %d, %d" ...);
something like that. Note that scanf is not recommended to be used, getc is a neat alternative, though also annoying when you want to read numbers with more than one digit, but you could create a function read_number, which, based on getc, will read a number as a string and return the int value with stoi.

How to sort an array that going down and then going up, to array that going down all the way?

I have an assignment to make a function that sort array that going down and then going up (for example: 9, 8, 7, 6, 5, 7, 11, 13) to array that going down all the way (for example: 13, 11, 9, 8, 7, 7, 6, 5).
I wrote this in online compiler (programiz), but it just doesn't work for me.
#include <stdio.h>
#include <stdlib.h>
#define N 10
void sort_dec_inc(int a[], int n) {
int pivot, i, q = 0;
int c[n];
for (i=0; i<n; i++) {
c[i] = 0;
}
for (i=0; i<n-1; i++) {
if (a[i]<a[i+1]) {
pivot=i+1;
break;
}
}
if (pivot == n-1) {
return;
}
for (i=0; i<pivot && n>=pivot; q++) {
if (a[i]>=a[n]) {
c[q] = a[i];
i++;
}
else {
c[q] = a[n];
n--;
}
}
if (n==pivot) {
while(i<pivot) {
c[q] = a[i];
q++;
i++;
}
}
else {
while (n>=pivot) {
c[q] = a[n];
q++;
n--;
}
}
for(i=0; i<n; i++) {
a[i] = c[i];
}
}
int main()
{
int num_arr[N] = {9, 7, 5, 3, 1, 2, 4, 6, 8, 10};
sort_dec_inc(num_arr, N);
int i;
for(i = 0; i < N; i++) {
printf("%d ", num_arr[i]);
}
return 0;
}
output (most of the times) : 9 7 5 3 1 2 4 6 8 10
Sometimes the output is different, for example: (410878976 10 9 8 1 2 4 6 8 10 )
If someone can answer in simple code its the best, I don't understand yet all the options in C.
(I'm sorry if its a clumsy code, I'm new for this.)
thanks a lot!
Solution based on the comments below:
#include <stdio.h>
#include <stdlib.h>
#define N 10
void sort_dec_inc(int a[], int n) {
int left, i = 0;
int right = n-1;
int c[n];
while (i<n) {
if (a[left] >= a[right]) {
c[i] = a[left];
left++;
}
else {
c[i] = a[right];
right--;
}
i++;
}
for(i=0; i<n; i++) {
a[i] = c[i];
}
}
int main()
{
int num_arr[N] = {9, 7, 5, 3, 1, 2, 4, 6, 8, 10};
sort_dec_inc(num_arr, N);
int i;
for(i = 0; i < N; i++) {
printf("%d ", num_arr[i]);
}
return 0;
}
output: 10 9 8 7 5 5 4 3 2 1
For starters it is a bad idea to define an auxiliary variable length array. Such an approach is unsafe because the program can report that there is no enough memory to allocate the array.
At least this code snippet
for (i=0; i<n-1; i++) {
if (a[i]<a[i+1]) {
pivot=i+1;
break;
}
}
if (pivot == n-1) {
return;
}
contains a logical error.
Consider an array that contains only two elements { 1, 2 }. In this case a[0] is less than a[i+1] that is than a[1]. So the condition of the if statement
if (pivot == n-1) {
return;
}
evaluates to logical true and the function returns the control though the array was not sorted in the descending order. It stays unchanged.
Or consider this code snippet
if (a[i]>=a[n]) {
c[q] = a[i];
i++;
}
The expression a[n] accesses memory beyond the array that results in undefined behavior.
A straightforward approach is to use the method insertion sort.
Here is a demonstration program.
#include <stdio.h>
#include <string.h>
void insertion_sort( int a[], size_t n )
{
size_t i = 1;
while ( i < n && !( a[i-1] < a[i] ) ) i++;
for ( ; i < n; i++ )
{
size_t j = i;
while ( j != 0 && a[j-1] < a[i] ) --j;
if ( i != j )
{
int tmp = a[i];
memmove( a + j + 1, a + j, ( i - j ) * sizeof( int ) );
a[j] = tmp;
}
}
}
int main( void )
{
int a[] = { 9, 7, 5, 3, 1, 2, 4, 6, 8, 10 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
insertion_sort( a, N );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
}
The program output is
9 7 5 3 1 2 4 6 8 10
10 9 8 7 6 5 4 3 2 1
I would recommend a bubble sort.
It is an easy way to sort numbers in numerical order:
for (int i = 0; i < quant; i++)
{
for (int j = 0; j < quant-1; j++)
{
if (Array[j] < Array[j + 1])
{
int temp = Array[j];
Array[j] = Array[j + 1];
Array[j + 1] = temp;
}
}
}
quant is the quantity of numbers you want to sort. Don't forget to define an integer array with length quant for the sorting process.
To access the array, just use a for loop to return all the results.

What parameters to set as main loop

Okay, so I have a homework question, which goes as follows: From the array make pairs (b, c) where b is lowest even number, and c is biggest. Write numbers in output, remove them from the array and continue the loop until there are no more even numbers, or the array is empty.
EDIT: If there is only 1 even number, output it as the biggest and lowest number at the same time, so that the final array has no even numbers.
Here is what I did for now:
int a[100], b, c, n;
b = 9999999;
c = -9999999;
printf("Input array length: ");
scanf("%d", &n);
printf("Input elements of array: ");
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
for (int i = 0; i < n; i++) {
if (a[i] < b && a[i] % 2 == 0)
b = a[i];
}
for (int i = 0; i < n; i++) {
if (a[i] > c && a[i] % 2 == 0)
c = a[i];
}
printf("\n%d %d\n", b, c);
return 0;
I set absurd values for b and c on start so that I 99% sure there will be numbers from the array that is lower/higher from those values (I tried to set them as NULL but that didn't). So my question is how to set the main loop that will circle until there are no even numbers or array is empty? Also is there another way I can initialize b and c.
Also, for removing even numbers, I was thinking about doing something like this:
for (int i = pos; i < n; i++)
a[i] = a[i+1];
n--;
Where pos is an index of the even element.
You can not resize an array but you can track its size of actual elements.
I suppose that if in the array there is only one even element then there is no pair of the minimum and maximum even elements in the array. So in this case nothing is "removed" from the array and the process stops. However you can change the approach and "remove" even a single even element.
And the request of the assignment to remove elements means that the order of the elements in the array must be kept. You may not sort the array.
That is when you are asked to remove an element from an array then this does not mean that you are to sort the array.:)
Here is a demonstrative program.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
struct Pair
{
size_t min;
size_t max;
};
struct Pair minmax_element( const int a[], size_t n )
{
struct Pair p = { n, n };
for ( size_t i = 0; i < n; i++ )
{
if ( a[i] % 2 == 0 )
{
if ( p.min == n || a[i] < a[p.min] ) p.min = i;
if ( p.max == n || a[p.max] < a[i] ) p.max = i;
}
}
return p;
}
int main(void)
{
enum { N = 20 };
int a[N];
srand( ( unsigned int )time( NULL ) );
for ( size_t i = 0; i < N; i++ ) a[i] = rand() % N;
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
int success = 1;
size_t n = N;
while ( success )
{
struct Pair p = minmax_element( a, n );
success = p.min != n && p.max != n;
if ( success )
{
printf( "minimum even number = %d, maximum even number = %d\n",
a[p.min], a[p.max] );
if ( p.max < p.min )
{
size_t tmp = p.min;
p.min = p.max;
p.max = tmp;
}
memmove( a + p.max, a + p.max + 1, ( n - p.max - 1 ) * sizeof( int ) );
--n;
memmove( a + p.min, a + p.min + 1, ( n - p.min - 1 ) * sizeof( int ) );
--n;
}
}
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
return 0;
}
Its output might look like
8 3 6 16 3 4 9 8 1 4 15 9 16 12 3 7 10 19 15 15
minimum even number = 4, maximum even number = 16
minimum even number = 4, maximum even number = 16
minimum even number = 6, maximum even number = 12
minimum even number = 8, maximum even number = 10
3 3 9 8 1 15 9 3 7 19 15 15
As it is seen in the result array there is one even element with the value 8 because the array does not have any more even element to make a pair.
Edit: Taking into account your comment
Oh sorry, I forgot to mention that if there is only 1 element (in this
example 8), you simply output it 2 times at the and, as the lowest and
biggest number, so that the final output has no even numbers.
the demonstrative program can look the following way
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
struct Pair
{
size_t min;
size_t max;
};
struct Pair minmax_element( const int a[], size_t n )
{
struct Pair p = { n, n };
for ( size_t i = 0; i < n; i++ )
{
if ( a[i] % 2 == 0 )
{
if ( p.min == n || a[i] < a[p.min] ) p.min = i;
if ( p.max == n || a[p.max] < a[i] ) p.max = i;
}
}
return p;
}
int main(void)
{
enum { N = 20 };
int a[N];
srand( ( unsigned int )time( NULL ) );
for ( size_t i = 0; i < N; i++ ) a[i] = rand() % N;
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
int success = 1;
size_t n = N;
while ( success )
{
struct Pair p = minmax_element( a, n );
success = p.min != n;
if ( success )
{
if ( p.max == n ) p.max = p.min;
printf( "minimum even number = %d, maximum even number = %d\n",
a[p.min], a[p.max] );
if ( p.max < p.min )
{
size_t tmp = p.min;
p.min = p.max;
p.max = tmp;
}
memmove( a + p.max, a + p.max + 1, ( n - p.max - 1 ) * sizeof( int ) );
--n;
if ( p.min != p.max )
{
memmove( a + p.min, a + p.min + 1, ( n - p.min - 1 ) * sizeof( int ) );
-- n;
}
}
}
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
return 0;
}
Its output might look like
3 10 0 12 16 0 13 11 15 16 6 8 11 10 11 12 4 14 4 3
minimum even number = 0, maximum even number = 16
minimum even number = 0, maximum even number = 16
minimum even number = 4, maximum even number = 14
minimum even number = 4, maximum even number = 12
minimum even number = 6, maximum even number = 12
minimum even number = 8, maximum even number = 10
minimum even number = 10, maximum even number = 10
3 13 11 15 11 11 3
So, this problem is much much easier if you simply sort the array.
I would replace your current for loops with the following logic:
1) Sort the array from lowest to highest.
2) Increment through the array from both ends and pop out the highest and lowest values if and only if they are even.
3) Eventually your increments will meet in the middle and the loop can end when the two counters meet.
This is just a simple sort followed by a one for loop. Once they are popped you can set the values you popped to 0.
You need to set up an encompassing while loop that continues running so long as there are even elements in the array. You can break from this loop if you find no even elements in your iteration. Also it seems at the moment you haven't implemented deletion from the array; this can be done in several ways, but in my opinion the easiest is just to maintain a second "checked" array that stores 1's or 0's to signify if an element has been previously taken. As follows:
int seen[n];
for (int i = 0; i < n; i++){
seen[i] = 0;
}
while (1){
int flag = 0, ind1 = 0, ind2 = 0;
b = 0;
c = 0;
for (int i = 0; i < n; i++) {
if ((!flag || a[i] < b) && a[i] % 2 == 0 && !seen[i]){
flag = 1;
b = a[i];
ind1 = i;
}
}
flag = 0;
for (int i = 0; i < n; i++) {
if ((!flag || a[i] > c) && a[i] % 2 == 0 && !seen[i] && i != ind1){
flag = 1;
c = a[i];
ind2 = i;
}
}
if (!flag){
printf("No more even elements (or only one remaining) in the array.\n");
break;
}
seen[ind1] = 1;
seen[ind2] = 1; // "removing" them from the array
printf("\n%d %d\n", b, c);
}
Flag is set to 0 at the end of the second for loop if it's unable to find an even number that has yet to be taken, and breaks upon this condition.
This also solves the problem of initializing b and c. Your current approach to that is probably fine in most cases, but in this solution you simply set them to the first even value you find in the array (that hasn't been previously taken), since the minimum will be less than or equal to it, and the maximum greater than or equal to it.
As a side note, another (easier) way to "remove values" is to set them to odd numbers, since then you'll just pass over them in iteration. I decided not to go with this approach in interests of preserving the initial array, if it's what your teacher prefers.
The least I can think of is you can use a trick (not all teachers allow this, because it is kinda nonsense and considered as not doing the homework).
Make a variable odd[n] (not recommended), if you are worried about the memory used, you can simply do a for loop from 0 to n-1 to find how many odd numbers so you can make it like odd[n_odd].
Then you do a for loop from 0 to n-1, if the number is odd, assign it to odd[]. So you just need to print just the odd numbers. If it's necessary to find max & min even numbers and delete the pairs, you can ignore my comment (This is an idea instead of an answer). Otherwise, Vlad's answer is the correct one.

Majority element in an array.It

#include <stdio.h>
void main()
{
int maj, count, n = 6;
int arr[] = {1, 2, 2, 2, 2, 3, 4};
for (int i = 0; i < n; i++) {
maj = arr[i];
count = 0;
for (int j = 9; j < n; j++) {
if (arr[j] == maj) count++;
}
if (count > n / 2) {
break; /* I think some problem is here ,if majority element not found then it takes last element as the majority element */
}
}
printf("%d", maj);
}
It is giving correct output if majority ellement is there but incorrect output if no majority element is there for example if array is {1,2,3,4} it is giving output as 4. please help!!
#include <stdio.h>
int main() {
int maj, count, n = 7; //n is size of arr
int arr[] = {1, 2, 2, 2, 2, 3, 4};
int isFound = 0; //0 -> false, 1 -> true
for (int i = 0; i < n; i++) {
maj = arr[i];
count = 1; //first elements is itself
isFound = 0; //by default we assume that no major elements is found
for (int j = i+1; j < n; j++) { //iterate from next elements onwards to right in array
if (arr[j] == maj) count++;
}
if (count > n / 2) {
isFound = 1;
break; //major elements found; no need to iterator further; just break the loop now
}
}
if(isFound) printf("%d ", maj);
else printf("no major element");
return 0;
}
For starters according to the C Standard function main without parameters shall be declared like
int main( void )
Try not to use magic numbers. Usually as in your program they are a reason for program bugs. For example you declared the array arr as having 7 elements however the variable n that should keep the number of elements in the array is initialized with the value 6. Another magic number 9 is used in the loop
for (int j = 9; j < n; j++) {
^^^
There is no need to write the outer loop that travers the whole array. Also the program does not report the case when the majority number does not exist in the array.
Using your approach with two loops the program can look the following way
#include <stdio.h>
int main( void )
{
int a[] = { 1, 2, 2, 2, 2, 3, 4 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t i = 0;
for ( ; i < ( N + 1 ) / 2; i++ )
{
size_t count = 1;
for ( size_t j = i + 1; count < N / 2 + 1 && j < N; j++ )
{
if ( a[i] == a[j] ) ++count;
}
if ( !( count < N / 2 + 1) ) break;
}
if ( i != ( N + 1 ) / 2 )
{
printf( "The majority is %d\n", a[i] );
}
else
{
puts( "There is no majority element" );
}
return 0;
}
Its output is
The majority is 2

Resources