Find element in array with lowest difference from average in C - c

I need to set the size of array. After that I start to input numbers to dill this array. During that procedure I count sum for calculating average later.
Now I have an array and average and I need to find the element with lowest difference from average.
Like:
array size = 3
input = 1
input = 2
input = 3
average = 2
Counting
abs( 1 - 2 ) = 1
abs( 2 - 2 ) = 0
abs( 3 - 2 ) = 1
So the lowest difference have the element with value 2. And in the end of the program I need to out put that element from array and its index.
So far I came up with:
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char **argv )
{
int n = 0, i = 0;
double average = 0;
int sum = 0;
double tmp = 0;
double min = 0;
int index = 0;
int *a;
double *b;
printf("Amount of elements = ");
scanf("%d", &n);
if( 0 == n )
{
return 0;
}
if( n < 1 || n > 10 )
{
return 0;
}
a = ( int* )malloc( sizeof( *a ) * n );
b = ( double* )malloc( sizeof( *b ) * n );
while( i < n )
{
printf("Input number: ");
scanf("%d", &a[i]);
sum += a[i];
i++;
}
average = ( double )( sum / n );
printf("Average = %.3lf\n", average);
for( i = 0; i < n; i++ )
{
tmp = abs( ( double )( a[ i ] ) - average );
b[ i ] = tmp;
}
/* for( i = 0; i < n; i++ )
{
} */
free( a );
free( b );
return 0;
}
Update: My apologies. The question is how to achive the last part without macking this simple program even more complicated.
Thank you all for help.

You need to use the 2 variables defined to hold the lowest difference and index of the lowest difference in something like
min = b[0]; /* initialize min with b[0] */
index = 0; /* and index with 0 */
for( i = 1; i < n; i++ ) /* loop from 1 onwards ... index 0 was used for initialization */
{
/* maybe change min to b[i] */
/* and index to i */
}
free(a);
free(b);

Related

I want to insert in a vector multiple values in a location

When I create a vector , let's say size of 5 , elements are 1,2,3,4,5 and I want to add at the location( for example index 2) the numbers 200 and 300 , the vector should look like 1 ,2 ,200,300,3,4,5.
#include <stdio.h>
#include <stdlib.h>
int main(){
int v[] ={1,2,3,4,5,6,7};
int n = sizeof(v)/sizeof(int);
int location,element;
printf("Enter location:");
scanf("%d",&location);
printf("Enter element:");
scanf("%d",&element);
for(int i = n - 1; i >= location;i--){
v[i + 1] = v[i];
}
v[location] = element;
for(int i = 0; i <= n;i++){
printf("%d ",v[i]);
}
}
You need to loop like this
for(;;){
int location,element;
printf("Enter location:");
scanf("%d",&location);
if(location == -1)
break;
printf("Enter element:");
scanf("%d",&element);
for(int i = n - 1; i >= location;i--){
v[i + 1] = v[i];
}
v[location] = element;
}
BUT you code is severely broken, you are adding to a vector thats of fixed size. you cannot do that
In this code
for (int i = n - 1; i >= location; i--) {
v[i + 1] = v[i];
}
n is the count of number of elements, so on the first loop you do
v[n] = v[n-1]
ie
v[7] = v[6]
well v[7] is off the end of the array (array indexes are 0 to 6) Thats very bad
You declared a fixed size array
int v[] ={1,2,3,4,5,6,7};
You can not enlarge it.
Thus this loop
for(int i = 0; i <= n;i++){
printf("%d ",v[i]);
}
invokes undefined behavior due to using the index with the value n that is outside the valid range of indices [0, n) for the source array.
You need to allocate the array dynamically and when you are going to add one more element you will need to reallocate the array.
Here is a demonstration program.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main( void )
{
size_t n = 7;
int *v = malloc( n * sizeof( int ) );
memcpy( v, ( int [7] ){ 1, 2, 3, 4, 5, 6, 7 }, n * sizeof( int ) );
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", v[i] );
}
putchar( '\n' );
size_t location = 0;
printf( "Enter location: " );
scanf( "%zu", &location );
if ( n < location ) location = n;
int element = 0;
printf( "Enter element: " );
scanf( "%d",&element );
int *tmp = realloc( v, ( n + 1 ) * sizeof( int ) );
if ( tmp != NULL )
{
v = tmp;
memmove( v + location + 1, v + location, ( n - location ) * sizeof( int ) );
v[location] = element;
++n;
}
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", v[i] );
}
putchar( '\n' );
free( v );
}
The program output might look like
1 2 3 4 5 6 7
Enter location: 2
Enter element: 200
1 2 200 3 4 5 6 7

i want to add a constant to an array of numbers but differently in C

for example i have an array with elements
0 1 2 3 4 5 6
i want to add say 3 to all the elements and want this output:
3 4 5 6 0 1 2 after the addition the numbers should not exceed the largest element, but start from the smallest one.
Hard to explain.
Is there some way of doing this in c? (not c++)
What you are describing seems to be addition modulo the maximum element + 1, i.e., a sum greater than the maximum element wraps around.
Find the maximum element, let's call it max, by iterating over the array.
Iterate over the array again, and for each element do the addition modulo max + 1, i.e., conceptually arr[i] = (arr[i] + n) % (max + 1).
(If it was intended that the wrap-around is not to zero but to the minimum element, then also find the smallest value in stepĀ 1 and do arr[i] = ((arr[i] - min + n) % ((max - min) + 1)) + min in stepĀ 2.)
If I have understood correctly you need something like the following.
#include <stdio.h>
size_t max_element( const int a[], size_t n )
{
size_t max = 0;
for ( size_t i = 1; i < n; i++ )
{
if ( a[max] < a[i] ) max = i;
}
return max;
}
int main(void)
{
int a[] = { 0, 1, 2, 3, 4, 5, 6 };
const size_t N = sizeof( a ) / sizeof( *a );
int value = 0;
printf( "Enter a value to add to elements of the array: " );
scanf( "%d", &value );
size_t max = max_element( a, N );
int upper_value = a[max] + 1;
for ( size_t i = 0; i < N; i++ )
{
a[i] = ( a[i] + value ) % upper_value;
}
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
}
The program output might look like
Enter a value to add to elements of the array: 3
3 4 5 6 0 1 2

increase size of array

May you help me with this exercise please?
Write a C program that reads 6 integers from the keyboard and assigns the first 5 values at the first 5 positions of an array; store the sixth value in a variable N. Write a function that, given input the array initialized with the first 5 values from the keyboard and the integer N, returns the array resized to contain 5 + N elements, such that each one of the new N elements corresponds to the sum of the numbers before it in the array.
In main, print the content of the array returned by the function.
It's OK also all in the main function.
I have the problem when I have to use the function realloc to increment the array from size = 5 to 5 + N.
This is my code:
int N, a, i;
int *ptr;
int arr[6];
for (i = 0; i < 5; i++) {
printf("Insert number in array, position(%d): ", i);
scanf("%d", &arr[i]);
}
N = arr[4];
a = 5 + N;
ptr = (int *)realloc(arr, sizeof(int) * a);
for (i = 4; i < a; i++) {
ptr + i = N * N; //<--- **problem!!**
}
for (i = 0; i < a; i++) {
printf("%d\n", ptr[i]);
}
free(ptr);
You cannot reallocate an array defined locally in a function nor defined globally. You can only call realloc on an object previously allocated with malloc(), calloc() or realloc() or with a NULL pointer. So you must allocate the initial array with 5 elements in main() and reallocate it in the function.
#include <stdio.h>
#include <stdlib.h>
int *extend_array(int *arr, int N) {
int a = 5 + N;
arr = realloc(arr, a * sizeof(int));
if (arr != NULL) {
int sum = 0;
for (int i = 0; i < 5; i++) {
sum += arr[i];
}
for (int i = 5; i < a; i++) {
arr[i] = sum;
sum += sum;
}
}
return arr;
}
int main() {
int N;
int *arr = malloc(5 * sizeof(int));
if (arr == NULL) {
printf("allocation failed\n");
return 1;
}
for (int i = 0; i < 5; i++) {
printf("Insert number in array, position(%d): ", i);
if (scanf("%d", &arr[i]) != 1) {
printf("invalid input\n");
return 1;
}
}
printf("Insert the value of N: ");
if (scanf("%d", &N) != 1) {
printf("invalid input\n");
return 1;
}
int *ptr = extend_array(arr, N);
if (ptr == NULL) {
printf("reallocation failed\n");
} else {
arr = ptr;
for (int i = 0; i < 5 + N; i++) {
printf("%d\n", arr[i]);
}
}
free(arr);
return 0;
}
The assignment specifies that the function should take the array and the number N as arguments, but it would be better to make the initial size a variable and pass that to the function as well to make the code more generic, easier to extend, and less error prone as the constant 5 appears in many places.
If you need to reallocate an array then it initially must be allocated dynamically.
So this code
int arr[6];
//...
ptr = (int *)realloc(arr, sizeof(int) * a);
is invalid.
Pay attention to that according to the assignment you need to write a function that reallocates the array.
Bear in mind that it is a very bad style of programming to use "magic numbers" like 5. Instead use named constants or assign such numbers to variables and use them.
The program can look the following way.
#include <stdio.h>
#include <stdlib.h>
int * resize( int *a, size_t n, size_t m )
{
int *tmp = realloc( a, ( n + m ) * sizeof( int ) );
if ( tmp != NULL )
{
int sum = 0;
size_t i = 0;
while ( i < n ) sum += tmp[i++];
while ( i < n + m )
{
tmp[i] = sum;
sum += tmp[i++];
}
}
return tmp;
}
int main(void)
{
size_t n = 5;
int *a = malloc( n * sizeof( int ) );
size_t m = 0;
printf( "Enter %zu numbers. The last number shall be greater than 0: ", n + 1 );
for ( size_t i = 0; i < n; i++ )
{
scanf( "%d", a + i );
}
scanf( "%zu", &m );
int *tmp = resize( a, n, m );
if ( tmp != NULL )
{
a = tmp;
}
else
{
m = 0;
}
for ( size_t i = 0; i < n + m; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
free( a );
return 0;
}
The program output might look like
Enter 6 numbers. The last number shall be greater than 0: 1 2 3 4 5 6
1 2 3 4 5 15 30 60 120 240 480 960 1920 3840 7680

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.

Finding minimum difference between a pair of integers

Given the set of unsorted integers, how to find every pair of integers which have minimum difference. There are 3 samples as described below:
a = random.sample (range(-200,200), 5)
b = random.sample (range(-1000, 1000), 25)
c = random.sample (range(-2000, 2000), 50)
The expected output should be something like:
List A = [-85, -154, -33, 192, -160]
Minimum pairs for list A:
(-160, -154)
Catch! :)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct Pair
{
size_t first;
size_t second;
};
struct Pair minimum_difference( const int a[], size_t n )
{
struct Pair p = { 0 };
if ( 1 < n )
{
p.first = 0;
p.second = 1;
for ( size_t i = 0; i < n - 1; i++ )
{
for ( size_t j = i + 1; j < n; j++ )
{
// printf( "%d %d %llu\n", a[i], a[j],
// ( unsigned long long )abs( a[i] - a[j] ) );
if ( ( unsigned long long )abs( a[i] - a[j] ) <
( unsigned long long )abs( a[p.first] - a[p.second] ) )
{
p.first = i;
p.second = j;
}
}
}
}
return p;
}
int main(void)
{
const size_t N = 5;
const int UPPER_BOUND = 40 * N;
int a[N];
srand( ( unsigned int )time( NULL ) );
for ( size_t i = 0; i < N; i++ )
{
a[i] = rand() % ( 2 * UPPER_BOUND ) - UPPER_BOUND;
}
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
printf( "\n" );
struct Pair p = minimum_difference( a, N );
printf( "(%d, %d)\n", a[p.first], a[p.second] );
return 0;
}
The program output might look loke
119 9 -193 21 -43
(9, 21)
This prpgram finds only the first pair with the minimum difference. If there are several pairs with the minimum difference when you have to allocate dynamically an array of pairs. Of course the function will be changed.
The other approach is to use a sort-copy algorithm by using an additional array. And then traverse this array calculating the difference.

Resources