find smallest element of an array and set its index to 0 - c

I am trying to create a C function that takes an array, finds the smallest element, and sets the value of that element to zero.
This is my function so far.
void find_minimum(double a[], int n) {
int i, smallest = 0;
smallest = a[0];
for (i = 0; i < n; i++) {
if (a[i] < smallest) {
smallest = a[i];
}
a[i] = 0;
}
}
When I run it, every index except the last one is zero, but I want only the smallest element to be zero.

There's a few issues with your code, I'm surprised your compiler didn't explode on you.
void find_minimum(double a[], size_t n) {
size_t i, index;
double smallest;
// sanity check to make sure we're not accessing outside allocated memory
if (n > 0) {
smallest = a[0];
index = 0;
} else {
// nothing left to do here
return;
}
// start at 1 because 0 is initial default
for (i = 1; i < n; i++) {
if (a[i] < smallest) {
smallest = a[i];
index = i;
}
}
// assign only the smallest index
a[index] = 0.0;
}
Feel free to post comments if you have any questions.

If we're assuming only one smallest like the OP and some answers, we can also keep track of just the index of the smallest, instead of the value of the smallest, to keep things simple:
void find_minimum(double a[], size_t n) {
if (n <= 0) {
return;
}
size_t smallest = 0;
for (size_t i = 1; i < n; i++) {
if (a[i] < a[smallest]) {
smallest = i;
}
}
a[smallest] = 0.0;
}

I'd like to address the case where there are more then one unique smallest value.
In such a case, two loops are needed. One to find out the smallest value over the entire array and the other to set to zero all the elements with that value.
I'll keep track of the minimum and maximum index where this value appears in the array to minimize the range of the second loop:
void set_smallest_to_zero(double a[], size_t n) {
if ( !a || !n ) {
return;
}
double smallest = a[0];
size_t min_index = 0,
max_index = 0,
i;
// find the smallest values
for ( i = 1; i < n; ++i ) {
if ( a[i] > smallest ) {
continue;
} else if ( a[i] < smallest ) {
smallest = a[i];
min_index = i;
max_index = i;
} else { // a[i] == smallest
max_index = i;
}
}
// set to zero all the the minimum values
for ( i = min_index; i <= max_index; ++i ) {
if ( a[i] == smallest ) {
a[i] = 0.0;
}
}
}
HERE there is a live example.

Related

Smallest odd number in given array

This code is supposed to find the smallest odd number in given array and store it in min but when I try to print min it always prints 0.
int smallestodd(int x[5]){
int j;
int k[5];
int p = 0;
int r = 0;
for(int h =0; h<5;h++){
j = x[h] % 2;
if(j == 1){
int temp =x[h];
k[p] =temp;
p++;
}
}
int min = k[0];
while(k[r] !=0){
if(k[r] < min ){
min = k[r];
r++;
}
}
return min;
}
Assuming there is an odd number in the array -- let's say trying to find the minimum odd number in an array with just even numbers (or no numbers) is UB :)
index = 0;
while (arr[index] % 2 == 0) index++; // skip even numbers
min = arr[index++]; // first odd number
while (index < length) {
if (arr[index] % 2) {
if (arr[index] < min) min = arr[index];
}
index++;
}
this code avoid overflow in search and return 1 when found or 0 if array has only even numbers.
int getMinOdd(int arr[], int length, int *value) {
int found = 0;
for(int idx=0; idx < length; idx++) {
if (arr[idx] % 2) {
if (!found || *value > arr[idx]) {
*value = arr[idx];
}
found = 1;
}
}
return found;
}
It's quite simple actually. You need to just check 2 conditions on your array.
int smallestOdd(int arr[]){
int min = 99999; //Some very large number
for(int i = 0; i < (length of your array); i++) {
if(arr[i]%2 != 0 && arr[i] < min) { //Check if number is odd and less than the current minimum value
min = arr[i];
}
}
return min;
}
Use this using statement as first :
Using System Linq;
Console.WriteLine(myArray.Where(i => i%2 == 1).Min());

Finding minimum element in an integer array

What is wrong in the following program? Why isn't it returning smallest element as i have tried to implement. Kindly spot the errors.Please tell me the errors regarding the logic and the syntax.
#include<stdio.h>
int ArrayMinimum(int a[], size_t size);
#define SIZE 9
int main()
{
int a[SIZE];
for (int i = 0; i < SIZE; i++)
{
a[i] = 1 + rand() % 99;
printf("%d ", a[i]);
}
printf("\n\nThe smallest number of the array is %d \n", ArrayMinimum(a, SIZE));
}
int ArrayMinimum(int a[], size_t size)
{
if (size == 1)
{
return a[0];
}
for (int i = 0; i <= size ; i++)
{
if (a[i] > a[i + 1])
{
int temp = a[i + 1];
a[i + 1] = a[i];
a[i] = temp;
}
}
int b[] = { 0 };
for (int y = 0; y < size; y++)
{
b[y] = a[y];
}
ArrayMinimum(b, size -1 );
}
Your function is defined to return an int; and it will return an integer value, if and only if size == 1.
If size has another value, it will not return anything at all!
Where is a second return statement?
There are other substantial problems, such as the size of Array b is not well defined, and you overwrite memory there.
You have't put #include <stdlib.h> at the top of your file and as a result, the functions you called were assumed to accept an unknown number of arguments and return a value of type int. This causes undefined behavior.
Implicit declaration of functions srand, rand and system
Also your ArrayMinimum() is wrong.The SIZE constant is always equal to 9 and it gets passed in this method and used by the size variable.Hence it will never satisfy the 'if' condition of this method.With that the BubbleSort mechanism you have implemented is also wrong.Your code just swaps the values only once.
Use this approach to find the minimum of the array:-
minimum = array[0];
for (c = 1; c < size; c++)
{
if (array[c] < minimum)
{
minimum = array[c];
location = c+1;
}
}
Your ArrayMinimum logic is attempting to sort the array and has logical issues with no return defined if size > 1.
If the purpose is to return the minimum value, a simpler logic can be as follows.
int ArrayMinimum(int a[], size_t size)
{
int min = a[0];
if (size == 1)
{
return a[0];
}
for (int i = 1; i < size ; i++)
{
if (a[i] < min)
{
min = a[i];
}
}
return min;
}

Minimum sum of two elements from two arrays such that indices are not same

Given two arrays ar1 and ar2, how can we find sum of two elements from two arrays such that indices are not same and their sum is minimum?
However, I have written the following, but I am not sure regarding storing the sum in a temporary variable and comparing the sum with the sum in the immediately next pass:
int twinArrays(int ar1_size, int* ar1, int ar2_size, int* ar2)
{
int temp;
for(int i = 0; i < ar1_size;i++)
{
for(int j=0; j < ar2_size; j++) {
int sum=0;
if( i != j)
sum = ar1[i] + ar2[j];
}
}
return temp;
}
}
Suggestions in C would be helpful.
The minimal sum of 2 elements from 2 arrays is the sum of its minimum elements.
But, what happens when any of the arrays is 0 size...? The formulation of the question is undefined in this regard.
The following worst-case time complexity is O(N) and worst-case space complexity is O(1):
#include <limits.h>
int twinArrays(int ar1_size, int* ar1, int ar2_size, int* ar2)
{
int min1 = INT_MAX, min2 = INT_MAX;
for(int i = 0; i < ar1_size; i++)
min1 = ar1[i] < min1? ar[1]: min1;
for(int i = 0; i < ar2_size; i++)
min2 = ar2[i] < min2? ar2[1]: min2;
if (min1 > 0 && min2 > INT_MAX - min1) {
/* handle overflow */
return INT_MAX;
} else if (min1 < 0 && min2 < INT_MIN - min1) {
/* handle underflow */
return INT_MIN;
}
return min1 + min2;
}
Your code was not so far of one solution, but:
temp should have been initialized to value big enough to be under the wanted result,
when i != j, you should have compared sum to temp to store the result if sum was under temp,
return was miss placed.
So your corrected code could looks like:
#include <limits.h>
int twinArrays(int ar1_size, int* ar1, int ar2_size, int* ar2)
{
int sum_min = INT_MAX;
/* for each element in ar1 */
for (int i = 0; i < ar1_size; i++)
{
/* for each element in ar2 */
for (int j = 0; j < ar2_size; t++)
{
/* go to next j if indices are the same */
if (i != j)
{
/* compute sum */
int sum = ar1[i] + ar2[j];
/* compare to best */
if (sum < sum_min)
{
/* remember the best */
sum_min = sum;
}
}
}
}
return sum_min;
}

Sorting one array into another- C

So I am trying to write this function where the input parameter array will be taken and copied into another array but in a sorted way. For example: an input parameter of 3, 1, 9, 8 will copy into the target array 1, 3, 8, 9.
This is what I have so far but it only copies the smallest element in every time. I'm looking for a way to "blacklist" smallest values that are discovered in each pass.
void sort_another_array(int *param, int *target, int size){
int i, j, lowest = param[0];
for(i = 0; i < size; i++){
for(j = 0; j < size; j++){
if(param[j] < lowest){
lowest = param[j]
}
}
target[i] = lowest;
}
}
Of course I could have another array of already found lowest values but that's more unnecessary looping and checking and adds to the already terrible n^2 complexity. Is there an easier way to do this?
I'm completely new to C, so please do restrict it to simple programming concepts of logic statements, using some flag variables etc..
The probably most straight-forward way to do this is to first copy the whole array and then sort the new array in-place using a standard sorting algorithm.
However, if you want to keep the current structure, the following would be an alternative when all elements are unique:
void sort_another_array(int *param, int *target, int size) {
int i, j, past_min = INT_MAX, current_min = INT_MAX;
for (i = 0; i < size; ++i) {
for (j = 0; j < size; ++j) {
if (i == 0 || param[j] > past_min) {
if (past_min == current_min || param[j] < current_min) {
current_min = param[j];
}
}
}
target[i] = current_min;
past_min = current_min;
}
}
What this does is keeping track of the previously lowest element found (past_min). The next element to find is lowest among all elements greater than past_min. I.e., we want both param[j] > past_min and param[j] < current_min to be true. However, the first element to add to target (i.e., when i == 0) will not have a lower element before it, so we add an exception for that. Similar, the first element satisfying param[j] > past_min in a pass will not have any element to compare with so we add another exception using past_min == current_min (this is true only for the first element found in a pass).
If you have duplicates in the array, this might work:
void sort_another_array(int *param, int *target, int size) {
int j, past_min, current_min, write = 0, round_write = 0;
while (round_write != size) {
for (j = 0; j < size; ++j) {
if (round_write == 0 || param[j] > past_min) {
if (write == round_write || param[j] < current_min) {
current_min = param[j];
write = round_write;
target[write] = current_min;
++write;
} else if (param[j] == current_min) {
target[write] = current_min;
++write;
}
}
}
round_write = write;
past_min = current_min;
}
}
Basically it's the same idea, but it writes all elements of the minimum value in the same pass.
You can use a modified insertion sort algorithm to solve this problem:
#include <stdio.h>
void sort_another_array(int *param, int *target, int size)
{
for ( int i = 0; i < size; i ++ ) // do for all elements in param
{
int j = i - 1;
while ( j >= 0 && target[j] > param[i] ) // find index of element in target which is samler or equal than param[i]
{
target[j+1] = target[j]; // shift forward element of target which is greater than param[i]
j --;
}
target[j+1] = param[i]; // insert param[i] into target
}
}
#define SIZE 10
int main( void )
{
int a[SIZE] = { 9, 8, 0, 2, 1, 3, 4, 5, 7, 6 };
int b[SIZE];
sort_another_array( a, b, SIZE );
for ( int i = 0; i < SIZE; i ++ )
printf( "%2d", b[i] );
return 0;
}
The solution I am providing, has a limitation that: If there are no duplicates in the array, then this will work:
void sort_another_array(int *param, int *target, int size)
{
int i, j, lowest;
for(i = 0; i < size; i++)
{
int k = 0;
if( i > 0) // for all except first iteration
{
while(param[k] <= target[i-1]) // find the one greater than the last one added
k++;
}
lowest = param[k];
for(j = 1; j < size; j++)
{
if( ( i==0 && param[j] < lowest ) || ( i > 0 && param[j] < lowest && param[j] > target[i-1])) // for all except first iteration the min found should be greater than the last one found
{
lowest = param[j];
}
}
target[i] = lowest;
}
}

how to get ascender element in a array?

Consider a zero-indexed array A of N integers. Indices of this array are integers from 0 to N−1. Take an index K.
Index J is called an ascender of K if A[J] > A[K]. Note that if A[K] is a maximal value in the array A, then K has no ascenders.
Ascender J of K is called the closest ascender of K if abs(K−J) is the smallest possible value (that is, if the distance between J and K is minimal).
Note that K can have at most two closest ascenders: one smaller and one larger than K.
Here is a C++ solution where complexity is O(n).
Note that there are two loops however each iteration the number of element goes by a factor of 1/2 or the search range goes up by a factor of x2.
For example the first iteration take N time, but the second iteration is already N/2.
vector<long> ascender(vector <long> A)
{
long N = A.size();
vector<long> R(N,0);
vector<long> IndexVector(N,0); //This vector contains the index of elements with R=0
vector<long> RangeVector(N,0); //This vector define the loop range for each element
IndexVector[N-1]=N-1;
unsigned long CompxTest = 0;
for (long counter=0;counter<N;counter++)
{
IndexVector[counter] = counter; // we start that all elements needs to be consider
RangeVector[counter] = 1; // we start by looking only and neighbors
}
long Length = N;
long range;
while (Length>1)
{
long index = 0;
cout<<endl<<Length;
long J;
for (long counter=0;counter<Length;counter++)
{
CompxTest++; // Just to test complexity
J = IndexVector[counter]; // Get the index that need to be consider
range = RangeVector[J];
//cout<<" ("<<A[J]<<","<<J<<")";
if (range > N)
{
cout<<endl<<"Mini assert "<<range<<" N "<<N;
break;
}
if (J<(N-range) && A[J+range] > A[J])
{
R[J] = range;
}
if (J<(N-range) && A[J+range] < A[J] && R[J+range]==0)
{
R[J+range] = range;
}
if (J<(N-range) && A[J] == A[J+range] && R[J+range]==0)
{
R[J+range] = - range;
}
if (R[J]==0) // Didn't find ascender for this element - need to consider in next iteration
{
if (R[J+range]>2) //We can increase the range because the current element is smaller
RangeVector[J] += R[J+range]-2;
if (R[J+range]<-2)
RangeVector[J] += -R[J+range]-2;
RangeVector[J]++;
IndexVector[index] = J;
index++;
}
}
Length = index;
}
for (long counter=0;counter<N;counter++)
{
if (R[counter] < 0)
{
unsigned Value = abs(R[counter]);
if (counter+Value<N && A[counter]<A[counter+Value])
R[counter] = Value;
if (counter > Value && R[counter-Value]==0)
R[counter] = 0;
R[counter] = Value + R[counter-Value];
if (counter > Value && Value < R[counter - Value])
{
long PossibleSolution = R[counter - Value] + Value;
if (PossibleSolution <N && A[PossibleSolution]>A[counter])
R[counter] = abs(counter - PossibleSolution);
}
}
}
cout<<endl<<"Complex "<<CompxTest;
return R;
}
//
// C++ using multimap. -- INCOMPLETE
// The multimap MM is effectively the "inverse" of the input array AA
// since it is ordered by pair(value, index), where index refers to the index in
// input array AA, and value is the value in AA at that index.
// Input AA is of course ordered as (index, value).
// So when we read out of MM in value order, (a sorted set of values), each value
// is mapped to the index in the original array AA.
//
int ascender(int AA[], int N, int RR[]) {
multimap<int, int> MM;
// simply place the AA array into the multimap
int i;
for (i = 0; i < N; i++) {
int value = AA[i];
int index = i;
MM.insert(make_pair(value, index));
}
// simply read the multimap in order,
// and set output RR as the distance from one value's
// original index to the next value's original index.
//
// THIS code is incomplete, since it is wrong for duplicate values.
//
multimap<int, int>::iterator pos;
for (pos = MM.begin(); pos != MM.end(); ++pos) {
int value = pos->first;
int index = pos->second;
++pos;//temporarily move ahead to next item
// NEED to FURTHER CONSIDER repeat values in setting RR
RR[index] = (pos)->second - index;
--pos;
}
return 1;
}
1. Sort the array (if not pre-sorted)
2. Subtract every element with its adjacent element and store result in another
array.
Example: 1 3 5 6 8 -----> (after subtraction) 2 2 1 2
3. Find the minimal element in the new array.
4. Device a logic which would relate the minimal element in the new array to the
two elements in the original one.
public class Solution {
final static int MAX_INTEGER = 2147483647;
public static int maximal(int[] A) {
int max = A[0];
int length = A.length;
for (int i = 1; i < length; i++) {
if (A[i] > max) {
max = A[i];
}
}
return max;
}
public static int ascender(int[] a,int length, int k) {
int smallest = MAX_INTEGER;
int index = 0;
if (k<0 || k>length-1) {
return -1;
}
for (int i = 0; i < length; i++) {
// Index J is called an ascender of K if A[J] > A[K].
if(a[i] > a[k]) {
int abs = Math.abs(i-k);
if ( abs < smallest) {
smallest = abs;
index = i;
}
}
}
return index;
}
public static int[] array_closest_ascenders(int[] A) {
int length = A.length;
int[] R = new int[length];
for (int K = 0; K < length; K++) {
// Note that if A[K] is a maximal value in the array A,
// then K has no ascenders.
// if K has no ascenders then R[K] = 0.
if (A[K] == maximal(A)) {
R[K] = 0;
break;
}
// if K has the closest ascender J, then R[K] = abs(K-J);
// that is, R[K] is equal to the distance between J and K
int J = ascender(A, A.length, K);
if (J != -1) {
R[K] = Math.abs(K - J);
}
}
return R;
}
public static void main(String[] args) {
int[] a = { 4, 3, 1, 4, -1, 2, 1, 5, 7 };
/* int[] a = {-589630174, 806785750, -495838474, -648898313,
149290786, -798171892, 584782920, -288181260, -252589640,
133741336, -174886978, -897913872 }; */
int[] R = array_closest_ascenders(a);
for (int element : R) {
System.out.print(element + " ");
}
}
}
Some notes about the code. I guess break in array_closest_ascenders method should be replaced by continue so that all elements are analyzed for their ascenders.
And, surely, maximal(A) have to be moved out of a loop; instead assign maximal value to some variable before entering the loop and use it within the loop, thus avoiding redundant calculation of max value.
Here is C# Solution
class Program
{
static void Main(string[] args)
{
int[] A = new int[] { 4, 3, 1, 4, -1, 2, 1, 5, 7 };
int[] B = new int[A.Length];
int[] R = new int[A.Length];
Program obj = new Program();
obj.ABC(A,B, R);
}
public void ABC(int[] A,int[]B, int[] R)
{
int i, j, m,k;
// int temp = 0;
int n = A.Length - 1;
for (i = 0; i < n; i++)
{
for (j = 0; j <= n; j++)
{
if (A[i] < A[j])
{
m = Math.Abs(j - i);
R[i] = m;
break;
}
}
for (j = i-1; j > 0; j--)
{
if (A[i] < A[j])
{
k = Math.Abs(j - i);
B[i] = k;
break;
}
}
}
for (i = 0; i < n; i++)
{
if (R[i] > B[i] && (B[i] == 0))
{
R[i] = R[i];
//Console.WriteLine(R[i]);
//Console.ReadLine();
}
else { R[i] = B[i]; }
}
}
}
Basically in the search function I compare the first element of the array with the one immediately right, if it's bigger this means it is the first closest ascendant. For the other elements I compare the one immediately at left and afterward the one immediately right his first right element. The first one which is bigger is the closest ascendant, and I keep iterate this way until I don't find an element bigger than one I am considering or I return 0.
class ArrayClosestAscendent {
public int[] solution(int[] A) {
int i;
int r[] = new int[A.length];
for(i=0;i<A.length;i++){
r[i] = search(A, i);
}
return r;
}
public int search(int[] A, int i) {
int j,k;
j=i+1;
k=i-1;
int result = 0;
if(j <= A.length-1 && (A[j]>A[i]))
return Math.abs(j-i);
j++;
while(k>=0 || j < A.length){
if(k >= 0 && A[k] > A[i]){
return Math.abs(i-k);
}else if(j < A.length && A[j] > A[i]){
return Math.abs(i-j);
}else{
j++;
k--;
}
}
return result;
}
}

Resources