How to retrieve closest value to mean and its location C - c

I was just wondering how you would get the closest value to the mean, the program retrieves input from the user and then outputs a 2D array, within the two ranges the user inputted. It then also outputs lowest and highest array values, the mean(all of this has been coded), I'm just unsure how to write a function to return the closest value in the array to the mean and then the location within the array.

Subtract the mean value from each element.
Take the absolute value of the result.
Store the position and element which have lowest difference.
int fnFindClosestVal(int arn2DArray[][6], int nRows, int nCols, double nTotal, int *posRow, int *posCol)
{
int nClosestValue = arn2DArray[0][0];
int nDiff = abs(arn2DArray[0][0] - nTotal);
int Row,Col;
for (nCountRows = 0; nCountRows < nRows; nCountRows++)
{
for (nCountCols = 0; nCountCols < nCols; nCountCols++)
{
if(abs(arn2DArray[nCountRows][nCountCols] - nTotal) < nDiff)
{
nDiff = abs(arn2DArray[nCountRows][nCountCols] - nTotal);
nClosestValue = arn2DArray[nCountRows][nCountCols];
*posRow = nCountRows;
*posCol = nCountCols;
}
}
}
return nClosestValue;
}

Related

using function to find max value in an array

Can someone please explain what I'm doing wrong. I need to use an array to find the max value of the percentages array and display that amount and the year in the corresponding years array.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int findHighNumber (double percentages[], int elements);
int main (void)
{
int index;
int elements;
int years[] = {2000, 2002, 2004, 2006, 2008, 2010, 2012};
double percentages[] = {6.7, 6.6, 8, 9, 11.3, 14.7, 14.6};
int sampleSizes[] = {187761, 444050, 172335, 308038, 337093, 1000, 346978};
int high = findHighNumber(percentages, elements);
printf ("%i had the highest percentage with autism at %.2lf%%.\n", years[high], percentages[high]);
return 0;
}
int findHighNumber (double percentages[], int elements)
{
int index, high;
high = percentages[0];
for (index = 1; index < elements; index++)
if (high < percentages[index])
{
high = percentages[index];
}
return high;
}
First, you have to declare the elements variable in main():
int elements = 7;
or even better:
int elements = sizeof(percentages) / sizeof(*percentages);
which computes the array size automatically.
Then, don't modify the elements variable in you loop.
If you do it, each time the current maximum is changed, you program your loop to stop after the next element, potentially missing the real maximum which can be located at the end of the array.
Then, like Bob said, you should return the index of the maximum, this way, you can retrieve the corresponding sampleSize, or year.
When you do years[high], you're using a percentage as an array index which can take any real value in [0,100], instead of an index which must stay in {0, 1, 2, 3, 4, 5, 6}.
What's more, you store high in an integer variable, resulting in a truncation of it's value. You may prefer to store it as a double variable.
So findHighNumber() can become:
int findHighNumber(double percentages[], int elements)
{
int index;
double high;
int high_index;
high_index = 0;
high = percentages[high_index];
for (index = 1; index < elements; index++)
if (high < percentages[index]) {
high = percentages[index];
high_index = index;
}
return high_index;
}
The main() function now can become something like:
int main (void)
{
int years[] = {2000, 2002, 2004, 2006, 2008, 2010, 2012};
double percentages[] = {6.7, 6.6, 8, 9, 11.3, 14.7, 14.6};
int sampleSizes[] = {187761, 444050, 172335, 308038, 337093, 1000,
46978};
int elements = sizeof(percentages) / sizeof(*percentages);
int high_index = findHighNumber(percentages, elements);
printf ("%i had the highest percentage with autism at %.2lf%% (sample"
"size was %d).\n", years[high_index], percentages[high_index],
sampleSizes[high_index]);
return 0;
}
Then, some small advices:
putting a prototype of findHighNumber() is not needed, just define the function above the places where it's needed. This way, when you really have to put a prototype for a function, it a hint saying that you were forced to do so, (for example for mutually recursive functions), plus it shortens the code.
you should define a, for example, struct autism_sample like that:
struct autism_sample {
int year;
int sample_size;
double percentage;
};
This way, you just have to define one array:
struct autism_sample autism_samples[] = {
{
.year = 2000,
.sample_size = 187761,
.percentage = 6.7,
},
{
.year = 2002,
.sample_size = 444050,
.percentage = 6.6,
},
...
};
This way, your data is organized in a more logical way, less error-prone to maintain and you gain the choice, in the implementation of findHighNumber(), to return either the index of the maximum or directly, a pointer to the element holding the maximum, the index becomes then useless.
What's more, it's easier to (un)serialize...
I'm not sure if this is a typo here, but it appears while calling
int high = findHighNumber(percentages, elements);
you don't have a variable elements defined there. That said, you have another syntax error (missing the closing }) near
if (high < percentages[index])
{
high = percentages[index]; ///after this.
Finally, inside findHighNumber (), elements is local to the function, so, the only usage as elements = index+1; is useless.
Given the way you are storing and using data, you should return the index where the higher element is, not its value.
Also you have to pass the right size of the array (and don't change it inside the function), while you are passing an uninitialized value.
You should send the index instead of the value.
int findIndexOfMax (double percentages[], int elements) {
int index = 0;
int highIndex = 0;
double high = 0.0;
high = percentages[highIndex];
for (index = 1; index < elements; index++)
{
if (high < percentages[index])
{
high = percentages[index];
highIndex = index;
}
}
return highIndex;
}
You are returning the wrong value .. you should not return what's the highest value but you should return the index of it.
or you you can simply print the result that you want in the function you're calling.
Also, I don't see that you have initialized the variable elements.

Transform an array to another array by shifting value to adjacent element

I am given 2 arrays, Input and Output Array. The goal is to transform the input array to output array by performing shifting of 1 value in a given step to its adjacent element. Eg: Input array is [0,0,8,0,0] and Output array is [2,0,4,0,2]. Here 1st step would be [0,1,7,0,0] and 2nd step would be [0,1,6,1,0] and so on.
What can be the algorithm to do this efficiently? I was thinking of performing BFS but then we have to do BFS from each element and this can be exponential. Can anyone suggest solution for this problem?
I think you can do this simply by scanning in each direction tracking the cumulative value (in that direction) in the current array and the desired output array and pushing values along ahead of you as necessary:
scan from the left looking for first cell where
cumulative value > cumulative value in desired output
while that holds move 1 from that cell to the next cell to the right
scan from the right looking for first cell where
cumulative value > cumulative value in desired output
while that holds move 1 from that cell to the next cell to the left
For your example the steps would be:
FWD:
[0,0,8,0,0]
[0,0,7,1,0]
[0,0,6,2,0]
[0,0,6,1,1]
[0,0,6,0,2]
REV:
[0,1,5,0,2]
[0,2,4,0,2]
[1,1,4,0,2]
[2,0,4,0,2]
i think BFS could actually work.
notice that n*O(n+m) = O(n^2+nm) and therefore not exponential.
also you could use: Floyd-Warshall algorithm and Johnson’s algorithm, with a weight of 1 for a "flat" graph, or even connect the vertices in a new way by their actual distance and potentially save some iterations.
hope it helped :)
void transform(int[] in, int[] out, int size)
{
int[] state = in.clone();
report(state);
while (true)
{
int minPressure = 0;
int indexOfMinPressure = 0;
int maxPressure = 0;
int indexOfMaxPressure = 0;
int pressureSum = 0;
for (int index = 0; index < size - 1; ++index)
{
int lhsDiff = state[index] - out[index];
int rhsDiff = state[index + 1] - out[index + 1];
int pressure = lhsDiff - rhsDiff;
if (pressure < minPressure)
{
minPressure = pressure;
indexOfMinPressure = index;
}
if (pressure > maxPressure)
{
maxPressure = pressure;
indexOfMaxPressure = index;
}
pressureSum += pressure;
}
if (minPressure == 0 && maxPressure == 0)
{
break;
}
boolean shiftLeft;
if (Math.abs(minPressure) > Math.abs(maxPressure))
{
shiftLeft = true;
}
else if (Math.abs(minPressure) < Math.abs(maxPressure))
{
shiftLeft = false;
}
else
{
shiftLeft = (pressureSum < 0);
}
if (shiftLeft)
{
++state[indexOfMinPressure];
--state[indexOfMinPressure + 1];
}
else
{
--state[indexOfMaxPressure];
++state[indexOfMaxPressure + 1];
}
report(state);
}
}
A simple greedy algorithm will work and do the job in minimum number of steps. The function returns the total numbers of steps required for the task.
int shift(std::vector<int>& a,std::vector<int>& b){
int n = a.size();
int sum1=0,sum2=0;
for (int i = 0; i < n; ++i){
sum1+=a[i];
sum2+=b[i];
}
if (sum1!=sum2)
{
return -1;
}
int operations=0;
int j=0;
for (int i = 0; i < n;)
{
if (a[i]<b[i])
{
while(j<n and a[j]==0){
j++;
}
if(a[j]<b[i]-a[i]){
operations+=(j-i)*a[j];
a[i]+=a[j];
a[j]=0;
}else{
operations+=(j-i)*(b[i]-a[i]);
a[j]-=(b[i]-a[i]);
a[i]=b[i];
}
}else if (a[i]>b[i])
{
a[i+1]+=(a[i]-b[i]);
operations+=(a[i]-b[i]);
a[i]=b[i];
}else{
i++;
}
}
return operations;
}
Here -1 is a special value meaning that given array cannot be converted to desired one.
Time Complexity: O(n).

Segmentation fault (core dumped) error, in a C search function

I'm trying to write a C program to take an array of discrete positive integers and find the length of the longest increasing subsequence.
'int* a' is the array of randomly generated integers, which is of length 'int b'
call:
lis_n = answer(seq, seq_size);
function:
int answer(int* a, int b) {
if (a == NULL) {return -1;}
int i = 0;
int j = 0;
int k = 0;
//instantiate max and set it to 0
int max = 0;
//make an array storing all included numbers
int included[b];
memset(included, 0, b*sizeof(int));
//create a pointer to the index in included[] with the largest value
int indexMax = 0;
//create a pointer to the index in a[]
int indexArray = 0;
//index of a[] for max included
int maxToA = 0;
//set the first included number to the first element in a[]
included[indexMax] = a[indexArray];
//loop until break
while (1) {
if (a[indexArray] > included[indexMax]/*digit greater than last included*/) {
//include the digit
included[indexMax+1] = a[indexArray];
//increment current max pointer
indexMax++;
}
j = b - 1;
while (indexArray >= j/*pointer is at end"*/) {
if (j == (b - 1)) {
if ((indexMax+1) > max/*total is greater than current max*/) {
max = indexMax + 1;
}
}
if (a[b-1] == included[0]/*last element is in included[0], stop*/) {
return max;
} else {
//max included is set to zero
included[indexMax] = 0;
//max included pointer decreased
indexMax--;
//set array pointer to new max included
for (k=0;k<(b-1);k++) {
if (a[k] == included[indexMax]) {
indexArray = k;
}
}
//increment array pointer
indexArray++;
j--;
}
}
indexArray++;
printf("(");
for (i=0;i<b;i++) {
printf("%d,",included[i]);
}
printf(")");
}
}
I'm receiving 'Segmentation fault (core dumped)' in the terminal upon running.
Any help would be awesome.
You have declared
int indexMax = 0;
And here you use it as an array index
incuded[indexMax] = 0;
You increment and decrement it
indexMax++;
...
indexMax--;
You check its range but you don't limit it, you alter the value you compare it with
if ((indexMax+1) > max/*total is greater than current max*/) {
max = indexMax + 1;
}
You never check indexMax against b or with 0
int included[b];
So you are almost guaranteed to exceed the bounds of included[].
Some general points of advice. Make your function and variable names meaningful. Avoid making a premature exit from a function wherever possible. Avoid while(1) wherever possible. And never make assumptions about array sizes (including C "strings"). It might seem hard work putting in the overhead, but there is a payoff. The payoff is not just about catching unexpected errors, it makes you think about the code you are writing as you do it.
I've done something like this for homework before. I got help from:
https://codereview.stackexchange.com/questions/30491/maximum-subarray-problem-iterative-on-algorithm
Make sure you are not trying to index past the size of your array. What I would do would be to find out the size of array a[] (which looks like it is b) and subtract 1. Make sure you are not trying to access past the size of the array.

MQL4 array creating variables

I'm trying to make this function create X number of variables using an array. I know that this is technically wrong because I need a constant as my array's value (currently 'x'), but excluding that, what am I missing? Looked at so many code samples and can't figure it out, but I know it's got to be simple...
void variables()
{
int i;
int bars = 10;
int x = 1;
for (i = 1; i <= bars+1; i++)
{
int variables[bars] = { x };
x++;
if (i >= bars+1)
{
break;
}
}
void variables()
{
int bars = 10;
if(bars >= Bars) bars = Bars - 1;
// to be able to set array size based on variable,
// make a dynamically sized array
double highvalues[];
ArrayResize(highvalues, bars);
for (int i = 0 /*Note: Array index is zero-based, 0 is first*/; i <= bars; i++)
{
highvalues[i] = iHigh(NULL, 0, i);
// or
highvalues[i] = High[i];
}
}
It is hard to tell what do you want to achieve.
If you want to fill an array with a value ArrayFill() fill help you.

How to find which value is closest to a number in C?

I have the following code in C:
#define CONST 1200
int a = 900;
int b = 1050;
int c = 1400;
if (A_CLOSEST_TO_CONST) {
// do something
}
What is a convenient way to check whether if a is the closest value to CONST among a,b and c ?
Edit:
It doesn't matter if I have 3 variables or an array like this (it could be more than 3 elements):
int values[3] = {900, 1050, 1400};
This works for three variables:
if (abs(a - CONST) <= abs(b - CONST) && abs(a - CONST) <= abs(c - CONST)) {
// a is the closest
}
This works with an array of one or more elements, where n is the number of elements:
int is_first_closest(int values[], int n) {
int dist = abs(values[0] - CONST);
for (int i = 1; i < n; ++i) {
if (abs(values[i] - CONST) < dist) {
return 0;
}
}
return 1;
}
See it working online: ideone
Compare the absolute value of (a-CONST), (b-CONST) and (c-CONST). Whichever absolute value is lowest, that one is closest.
Here is a generalized method. The min_element() function takes an int array, array size, and pointer to a comparison function. The comparison predicate returns true if the first values is less than the second value. A function that just returned a < b would find the smallest element in the array. The pinouchon() comparison predicate performs your closeness comparison.
#include <stdio.h>
#include <stdlib.h>
#define CONST 1200
int pinouchon(int a, int b)
{
return abs(a - CONST) < abs(b - CONST);
}
int min_element(const int *arr, int size, int(*pred)(int, int))
{
int i, found = arr[0];
for (i = 1; i < size; ++i)
{
if (pred(arr[i], found)) found = arr[i];
}
return found;
}
int main()
{
int values[3] = {900, 1050, 1400};
printf("%d\n", min_element(values, 3, pinouchon));
return 0;
}
I m adding something in Mark Byres code.....
int is_first_closest(int values[]) {
int dist = abs(values[0] - CONST),closest; //calculaing first difference
int size = sizeof( values ) //calculating the size of array
for (int i = 1; i < size; ++i) {
if (abs(values[i] - CONST) < dist) { //checking for closest value
dist=abs(values[i] - CONST); //saving closest value in dist
closest=i; //saving the position of the closest value
}
}
return values[i];
}
This function will take an array of integers and return the number which is closest to the CONST.
You need to compare your constant to every element. (works well for 3 elements but it's a very bad solution for bigger elementcount, in which case i suggest using some sort of divide and conquer method). After you compare it, take their differences, the lowest difference is the one that the const is closest to)
This answer is a reaction to your edit of the original question and your comment.
(Notice that to determine the end of array we could use different approaches, the one i shall use in this particular scenario is the simplest one.)
// I think you need to include math.h for abs() or just implement it yourself.
// The code doesn't deal with duplicates.
// Haven't tried it so there might be a bug lurking somewhere in it.
const int ArraySize = <your array size>;
const int YourConstant = <your constant>;
int values[ArraySize] = { ... <your numbers> ... };
int tempMinimum = abs(YourArray[0] - YourConstant); // The simplest way
for (int i = 1; i < ArraySize; i++) { // Begin with iteration i = 1 since you have your 0th difference computed already.
if (abs(YourArray[i] - YourConstant) < tempMinumum) {
tempMinumum = abs(YourArray[i] - YourConstant);
}
}
// Crude linear approach, not the most efficient.
For a large sorted set, you should be able to use a binary search to find the two numbers which (modulo edge cases) border the number, one of those has to be the closest.
So you would be able to achieve O(Log n) performance instead of O(n).
pseudocode:
closest_value := NULL
closest_distance := MAX_NUMBER
for(value_in_list)
distance := abs(value_in_list - CONST)
if (distance < closest_distance)
closest_value := value_in_list
closest_distance := distance
print closest_value, closest_distance

Resources