Find array index if given value - arrays

I want to retrieve the index in the array where the value is stored. I know the value of the item at that point in the array. I'm thinking it's similar to the findIndex function in c#.
For example, array[2] = {4, 7, 8}. I know the value is 7, how do I get the value of the index, 1, if I know it is at array[1]?

For example you can define the corresponding function the following way
size_t FindIndex( const int a[], size_t size, int value )
{
size_t index = 0;
while ( index < size && a[index] != value ) ++index;
return ( index == size ? -1 : index );
}
Also instead of type size_t you can use type int.
But the better way is to use standard algorithm std::find or std::find_if declared in header <algorithm> provided that you use C++
For example
#include <algorithm>
#include <iterator>
int main()
{
int a[] = { 4, 7, 8 };
auto it = std::find( std::begin( a ), std::end( a ), 7 );
if ( it != std::end( a ) )
{
std::cout << "The index of the element with value 7 is "
<< std::distance( std::begin( a ), it )
<< std::endl;
}
}
The output is
The index of the element with value 7 is 1
Otherwise you have to write the function yourself as I showed abve.:)
If the array is sorted you can use standard C function bsearch declared in header <stdlib.h>
For example
#include <stdio.h>
#include <stdlib.h>
int cmp( const void *lhs, const void *rhs )
{
if ( *( const int * )lhs < *( const int * )rhs ) return -1;
else if ( *( const int * )rhs < *( const int * )lhs ) return 1;
else return 0;
}
int main()
{
int a[] = { 4, 7, 8 };
int x = 7;
int *p = ( int * )bsearch( &x, a, 3, sizeof( int ), cmp );
if ( p != NULL ) printf( "%d\n", p - a );
return 0;
}

First its important that the argument list contain size information for the array, i.e. passing a pointer to an array only does not provide enough information to know how many elements the array has. The argument decays into a pointer type with no size information to the function.
So given that, you could do something like this:
int findIndex(int *array, size_t size, int target)
{
int i=0;
while((i<size) && (array[i] != target)) i++;
return (i<size) ? (i) : (-1);
}
For small arrays this approach will be fine. For very large arrays, some sorting and a binary search would improve performance

Here's my version without a additional variable.
// Return index of element starting
// Return -1 if element is not present
int indexOf(const int elm, const int *ar, int ar_cnt)
{
// decreasing array count till it reaches negative
// arr_cnt - 1 to 0
while (ar_cnt--)
{
// Return array index if current element equals provided element
if (ar[ar_cnt] == elm)
return ar_cnt;
}
// Element not present
return -1; // Should never reaches this point
}
Hope the comments are self explanatory!

Related

MInimum element in array ( C )

I'm a newbie both here in stackoverflow and both in the world of programming.
Today i was solving some exercise about recursion, and one of these asked to write a recursive function for finding minimum element of an array.
After many tries, I have finally wrote this working code, but i want to ask you if this is a "good" code. I mean, the fact it's working aside, is it written well? There's something that should be changed? And, above all, there's a way to make this functions working well without declaring that global int "min"? :)
Here's the code:
#include <stdio.h>
int recursiveMinimum(int array[], size_t size);
int min = 1000;
int main(void) {
int array[] = {55, 5, 1, 27, 95, 2};
printf("\nMinimum element of this array is: %d\n\n",
recursiveMinimum(array, 6));
}
int recursiveMinimum(int array[], size_t size) {
if (size == 1) {
return min;
} else {
if (array[size] <= min) min = array[size];
return min = recursiveMinimum(array, size - 1);
}
}
It is a bad idea when a function depends on a global variable.
But in any case your function is incorrect and invokes undefined behavior.
In the first call of the function this if statement
if (array[size] <= min) min = array[size];
trying to access memory outside the passed array because the valid range of indices is [0, size).
Also the array can contain all elements greater than the initial value of the global variable
int min = 1000;
And the function may not be called a second time because the value of the variable min is unspecified.
The function should return the index of the minimal element in the array. In general the user can pass the second argument equal to 0. In this case again the function will invoke undefined behavior if you will try to return a non-existent element of an empty array.
The function can be declared and defined the following way
size_t recursiveMinimum( const int a[], size_t n )
{
if ( n < 2 )
{
return 0;
}
else
{
size_t min1 = recursiveMinimum( a, n / 2 );
size_t min2 = recursiveMinimum( a + n / 2, n - n / 2 ) + n / 2;
return a[min2] < a[min1] ? min2 : min1;
}
}
Here is a demonstration program
#include <stdio.h>
size_t recursiveMinimum( const int a[], size_t n )
{
if (n < 2)
{
return 0;
}
else
{
size_t min1 = recursiveMinimum( a, n / 2 );
size_t min2 = recursiveMinimum( a + n / 2, n - n / 2 ) + n / 2;
return a[min2] < a[min1] ? min2 : min1;
}
}
int main( void )
{
int a[] = { 55, 5, 1, 27, 95, 2 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t min = recursiveMinimum( a, N );
printf( "\nMinimum element of this array is: %d at the position %zu\n",
a[min], min );
}
The program output is
Minimum element of this array is: 1 at the position 2
Pay attention to that the first parameter has the qualifier const because the passed array is not being changed within the function. And to decrease the number of recursive calls the function calls itself for two halves of the array.
Recursion works by reducing the size at the call to the next iteration and comparing the result of the call with the current value and return the lower of the 2.
As recursion stop you can simply return the first element
int recursiveMinimum(int array[], size_t size) {
if (size == 1) return array[0];
int min_of_rest = recursiveMinimum(array, size - 1);
if (array[size - 1] <= min_of_rest) return array[size - 1];
return min_of_rest;
}
Full example: https://godbolt.org/z/sjnh8sYz3
In the past, we used to implement it with pointers, KR-C style.
Using pointers in a harsh way was a mean to deal with inefficiency of compilers at that time.
Not sure it is considered good practice now. An example is provided hereafter.
Anyway, it would be better (easier and more efficient) to implement it in a non recursive manner.
#include <stdio.h>
void recursiveMinimum(int *array, size_t size, int *min) {
if (size == 0) return;
if (*array < *min) *min = *array;
recursiveMinimum (array+1, size-1, min);
return;
}
int main(void) {
int array[] = {55, 5, 1, 27, 95, 2};
size_t size = sizeof(array)/sizeof(*array);
int min = array[0];
recursiveMinimum (array, size, &min);
printf("\nMinimum element of this array is: %d\n", min);
return 0;
}

What error did i make writing my recursive function using arrays?

#include <stdio.h>
#include <math.h>
int prod(int arr[], int n) {
if (arr[n-1] < 0) {
return 1;
}
return ((arr[n-1]) * (prod(arr[n-2] , n)));
}
int main( int argc, char* args[] ) {
int arr[] = {2 , 3};
printf("%d" , prod(arr , 2));
}
i keep getting pointer related errors but have no idea what to change, any help? The code is supposed to use the recursive function to get the product of all integers equal or over 0 in the array.
I guess the condition for termination of recursion should be:
if (n-1 < 0) {
return 1;
}
It can be reformulated as:
if (n <= 0) {
return 1;
}
What means that product of entries of empty array is 1.
Moreover, expression that goes deeper should be:
return arr[n-1] * prod(arr , n - 1);
The final code could be:
int prod(int arr[], int n) {
if (n == 0)
return 1;
return arr[n-1] * prod(arr, n - 1);
}
There should be assignment in the prod function with something like this:-
n=n-1
You are not decreasing the value of n anywhere.
This function is incorrect.
int prod(int arr[], int n) {
if (arr[n-1] < 0) {
return 1;
}
return ((arr[n-1]) * (prod(arr[n-2] , n)));
}
For starters this if statement
if (arr[n-1] < 0) {
return 1;
}
does not make a sense.
It seems you mean
if ( n-1 < 0) {
return 1;
}
In this expression
prod(arr[n-2] , n)
the first argument is a scalar object of the type int. That is arr[n-2] is an element of an array. Also the second argument shall be decremented that is you have to use the expression n - 1.
But apart from this there are several other drawbacks.
For starters a product of elements of an array can be too big to fit in an object of the type int, You should use at least the type long long int as the return function type or maybe the float type long double.
Secondly as the array is not being changed within the function then the first parameter should have the qualifier const.
The user can pass as second argument the value 0. In this case it will look strange that the function returns 1.
Thus the function should look at least like
long long int prod( const int arr[], size_t n )
{
return n == 0 ? 0 : ( n == 1 ? arr[n-1] : arr[n-1] * prod( arr, n - 1 ) );
}
Here is a demonstrative program
#include <stdio.h>
long long int prod( const int arr[], size_t n )
{
return n == 0 ? 0 : ( n == 1 ? arr[n-1] : arr[n-1] * prod( arr, n - 1 ) );
}
int main(void)
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
printf( "%lld\n" , prod( arr , sizeof( arr ) / sizeof( *arr ) ) );
return 0;
}
The program output is
3628800

How to edit an array in another function than the main function in c programming?

I'd like to increase each element in the array by one in another function than the main function. Then, I'd like to call this function and print in the main function.
#include <stdio.h>
int function(int array2[5]) {
int i;
while(i<4) {
array2[i]=array2[i]+1;
i++;
}
return array2[5];
}
int main() {
int array[5]={1,2,3,4,5};
int answer;
answer[5]=function(array[5]);
int j;
while(j<4) {
printf("%d \n",answer[j]);
j++;
}
return 0;
}
Some important things to know:
When you pass an array in C, you don't make a copy. It is the same array, so modifying the array that is passed in modifies the original.
The [] are operators and not part of the variable name.
The [] work differently in declaring a type than when used in an expression. array[5] gives you the 6th element in array, but int array[5] declares an array with 5 elements.
Accessing an element beyond the end of the allocated array has undefined behavior, but usually will crash.
If you declare a variable int answer it is not an array, and cannot become an array. It is just one int
If you want to make a copy of an array, you need to explicitly copy. There are standard libraries that might do it, but you should learn to copy each element, one by one, to the new array.
The return type int of the function does not make a sense.
int function(int array2[5]) {
And moreover you are trying to return the non-existent 6-th element of an array with only 5 elements.
return array2[5];
Within the function you are using uninitialized variable i
int function(int array2[5]) {
int i;
while(i<4) {
//...
that results in undefined behavior. Also the used magic number 4 does not make a sense at least because you are trying to pass to the function an array with 5 elements.
The function should be declared with a second parameter that specifiers the number of elements in the passed array. This function declaration
int function(int array2[5]);
does not mean that the passed to the function array has exactly 5 elements. The compiler will adjust the parameter declaration of the function to pointer to the array element type like
int function(int *array2);
In this statement in main
int answer;
answer[5]=function(array[5]);
you are using the subscript operator with an object of the scalar type int. So the compiler shall issue an error message.
Here is a demonstrative program that shows how the function can be defined.
#include <stdio.h>
void function( int a[], size_t n )
{
for ( ; n--; ++a )
{
++*a;
}
}
int main(void)
{
int a[] = { 1, 2, 3, 4, 5 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
function( a, N );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
return 0;
}
The program output is
1 2 3 4 5
2 3 4 5 6
There you go. I suppose this is what you want:
#include <stdio.h>
// Since the array named parameters are scoped only within its function,
// they are apart from your array in the main.
void function(int array[], int len) {
int i = 0;
while(i<len) {
array[i]=array[i]+1;
i++;
}
}
// Or alternatively you can process the array using a pointer
void functionWithPointer(int *array, int len) {
int i = 0;
while(i<len) {
*(array+i) = *(array+i)+1;
i++;
}
}
int main() {
int array[]={1,2,3,4,5};
// int answer; // Not necessary
int length = sizeof(array) / sizeof(int); // !!!ATTENTION
function(array, length);
// The array values updated by 1
printf("Array values after 1st update\n");
for(int k=0; k<length; k++) {
printf("%d \n",array[k]);
}
functionWithPointer(array, length);
// The array values updated by 1 again
printf("Array values after 2nd update\n");
int j;
while(j<length) {
printf("%d \n",array[j]);
j++;
}
return 0;
}
Here is the output:
Array values after 1st update
2
3
4
5
6
Array values after 2nd update
3
4
5
6
7

Function is not able to return elements in returnSize array in the problem

I tried to solve a C coding problem Two Sum in Online coding platform LeetCode
I am not able to return the integer pointer size.
Question:
Given an array of integers, return indices of the two numbers such that they add up to a specific target. You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
int i,j,sum=0,n1=0,n2=0,sz=1;
int *re;
re = (int*)malloc(sizeof(returnSize));
for(i=0;i<numsSize;i++){
if(sum==target){
break;
}
n1 = i;
for(j=i+1;j<numsSize;j++){
sum = nums[i]+nums[j];
if(sum==target){
n2 = j;
re[0] = n1;
re[1] = n2;
break;
}
}
}
return re;
}
“I expect the output of nums = [2, 7, 11, 15], target = 9, to be [0, 1], but the actual output is ]”
The interface of the function is designed to provide a two-part result, the array and its size.
You are not supposed to return the array by overwriting returnSize.
You are supposed to return the size of the returned array by writing it to the int variable referred by the pointer returnSize (and probably check that it is not a NULL pointer).
The array (i.e. the newly malloced pointer) is supposed to be returned via return, which of course you do. But doing that by overwriting return parameter pointer is what indirectly causes a problem here. (A mre would be required to trace the observed problem to this.)
By the way, I spotted this simply by seeing that you ignore and overwrite one of the parameters, the pointer. If that were correct, then the interface of the function would be inefficient. That can be the case, but usually not for challenges.
I can not reproduce the problem for the provided array. But in any case the function is incorrect..
Instead of this statement (where the argument of the malloc call does not make sense)
re = (int*)malloc(sizeof(returnSize));
^^^^^^^^^^^
there should be
re = (int*)malloc(sizeof( sizeof( int ) * *returnSize ));
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Though the parameter returnSize is redundant because the array according to your description has a fixed size equal to 2.
Moreover there is an unused variable sz=1
The function can invoke undefined behavior because in the case when the target is equal to 0 then the dynamically allocated array is not initialized and has indeterminate values because there is exit from the loop.
for(i=0;i<numsSize;i++){
if(sum==target){
break;
}
// ...
There is no need to dynamically allocate an array. You could return a structure of two elements.
The first parameter should be declared with the qualifier const.
The function can be written simpler and more clear and readable.
#include <stdio.h>
struct PairIndices
{
size_t first;
size_t second;
};
struct PairIndices twoSum( const int *a, size_t n, int target )
{
struct PairIndices pair = { n, n };
for ( size_t i = 0; i < n && pair.first == n ; i++ )
{
size_t j = 1;
while ( j < n && a[i] + a[j] != target ) j++;
if ( j != n )
{
pair.first = i;
pair.second = j;
}
}
return pair;
}
int main(void)
{
int a[] = { 2, 7, 11, 15 };
const size_t N = sizeof( a ) / sizeof( *a );
int target = 9;
struct PairIndices pair = twoSum( a, N, target );
if ( pair.first != N )
{
printf( "a[%zu] + a[%zu] == %d\n", pair.first, pair.second, target );
}
else
{
printf( "There are no two elements in the array "
"sum of which is equal to %d\n", target );
}
return 0;
}
The program output is
a[0] + a[1] == 9

problem by ordering a data structure using the qsort function in C

I need to order a array of data structure that contains information relating to a node origin, destination and weight. the problem is not ordered properly, because if two values ​​are equal to array.originNode simply takes the first value you get and not as it should be ordered.
This is how my code does order the structure
0 1 30
1 3 22
2 3 20
3 5 20
3 4 15
Process returned 0 (0x0) execution time : 0.015 s
Here's how it should order
0 1 30
1 3 22
2 3 20
3 4 15
3 5 20
I think the problem is the function that I am passing as parameter to qsort, which is not making the correct comparison. How do I change my comparison function to my code sorts the array of struct properly?
this is my full code
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <unistd.h>
typedef struct dataNodes{
int originNode;
int destinationNode;
int weight;
struct dataNodes *next;
} ARRAYS;
int function (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
int main() {
ARRAYS array[6];
int n = 5, i;
array [0].originNode = 3;
array [1].originNode = 3;
array[2].originNode = 1;
array[3].originNode = 0;
array[4].originNode = 2;
array [0].destinationNode = 4 ;
array [1].destinationNode = 5;
array[2].destinationNode = 3;
array[3].destinationNode = 1;
array[4].destinationNode = 3;
array [0].weight = 15;
array [1].weight = 20;
array[2].weight = 22;
array[3].weight = 30;
array[4].weight = 20;
qsort(array,n,sizeof(array[0]),function);
for(i=0; i<n; i++)
{
printf("%d %d %d\n",array[i].originNode,array[i].destinationNode,
array[i].weight);
}
return 0;
}
You need to change your compare function to compare ARRAY records properly. First compare originNode, and if they're the same compare destinationNode.
int function (const void * a, const void * b)
{
const ARRAYS *ap = a;
const ARRAYS *bp = b;
if( ap->originNode < bp->originNode )
return -1;
else if( ap->originNode > bp->originNode )
return 1;
else if( ap->destinationNode < bp->destinationNode )
return -1;
else if( ap->destinationNode > bp->destinationNode )
return 1;
else
return 0;
}
You are sorting an array of (uh...) ARRAYS. So your sort function that you pass in should be comparing ARRAYS objects. Your code treats it as int's.
To do secondary sorting, you need to compare the corresponding secondary fields in the case that the primary fields are equal. Do the same for any more fields you want to compare.
So in your case, this sort function could work for you:
int sort_ARRAYS (const void * a, const void * b)
{
/* the arguments are pointers to ARRAYS objects */
const ARRAYS *x = a;
const ARRAYS *y = b;
int cmp;
/* primary */
cmp = x->originNode - y->originNode;
if (cmp != 0) return cmp;
/* secondary */
cmp = x->destinationNode - y->destinationNode;
if (cmp != 0) return cmp;
/* tertiary */
return x->weight - y->weight;
}
From the fine manual:
void qsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *));
[...]
The compar argument is a pointer to the comparison function, which is called with two arguments that point to the elements being compared.
So your comparison function will receive two ARRAY * arguments disguised as const void * and your function just needs to cast them appropriately:
int
function(const void * a, const void * b) {
ARRAYS *aa = (ARRAYS *)a;
ARRAYS *bb = (ARRAYS *)b;
return aa->originNode - bb->originNode;
}
If you want a secondary sort key, then check if aa->originNode == bb->originNode and compare the secondary key if that's true; similarly for the tertiary key if needed.
Your current code is working by accident. This:
return ( *(int*)a - *(int*)b );
is actually comparing the first elements of the ARRAYS* arguments and it works because (a) there's no padding at the beginning of your structure and (b) originNode is at the beginning and it actually is an int.

Resources