calculate moving average of an static array in c - arrays

I wrote this code to calculate moving average of array in c.
Array_MovingAverage(const int inputSeries[],
size_t inputSize,
size_t window,
float output[],
size_t outputSize) {
if (inputSeries && output != NULL){
for(size_t i = 0; i < window ; i++)
if (window < inputSize)
if (inputSeries != NULL && output != NULL) {
if(outputSize >= inputSize) {
size_t inputSize[11] = {1, 2, 2, 3, 6, 8, 9, 2, 1, 2, 1};
const uint8_t window = 5;
{
const int inputSeries[] = {1, 2, 2, 3, 6, 8, 9, 2, 1, 2,1};
double window = 5;
double c = 2.0;
double d = 2.0;
for(int i = 0; i < window; i++)
{
c += inputSeries[i];
d = c / window;
}
return true;
}
}
}
}
}
I've been trying to calculate moving average of an array in C and get an desired output but it seems it doesn´t work. Can you please give me an advice how can I calculate moving average of an static array in C?
Output should be:
Moving Average: 1 2 2 3 6 8 9 2 1 2 1
0 0 0 0 3 4 6 6 5 4 3

Let's start from scratch. Your attempt to adapt this code is only making it very unclear what you are trying to do, and the original code appears to be flawed in any case. Going through the issues with the code is probably unproductive.
Firstly for a moving average N you keep a sum of the last N values, and for each new sample, you:
add sample[n] to sum
subtract sample[n-N] from sum
output sum / N
Taking your interface, but omitting the redundant outputSize - output is the same size as the input), an implementation might look like:
void Array_MovingAverage( const int* inputSeries,
size_t inputSize,
size_t window,
float* output )
{
int sum = 0 ;
if( inputSeries != NULL && output != 0 )
{
for( size_t i = 0; i < inputSize; i++ )
{
// Add newest sample
sum += inputSeries[i] ;
// Subtract oldest sample
if( i >= window )
{
sum -= inputSeries[i - window] ;
}
output[i] = (float)sum / window ;
}
}
}
To use it, you might have:
int main()
{
const int input[] = {1, 2, 2, 3, 6, 8, 9, 2, 1, 2, 1};
const size_t size = sizeof(input) / sizeof(*input) ;
float output[size] ;
Array_MovingAverage( input, size, 5, output ) ;
for( size_t i = 0; i < size; i++ )
{
printf( "%.2f\n", output[i]) ;
}
return 0;
}
For your sample data {1, 2, 2, 3, 6, 8, 9, 2, 1, 2, 1}, the output is:
{0.20, 0.60, 1.00, 1.60, 2.80, 4.20, 5.60, 5.60, 5.20, 4.40, 3.00}
Now it is not clear from your question, but form other comments it seems you wish to hack this function to ignore the input provided by the caller because you cannot modify the caller. Frankly that is bizarre, but here is a "safe" way of doing that. Let's assume the outputSize will be reinstated, because clearly you will need that to avoid overrunning the callers output buffer. The simplest solution is to wrap the whole body of the function is an additional shell of braces {...} allowing you to create shadow variables overriding the input parameters leaving the rest of the code untouched:
void Array_MovingAverage( const int* inputSeries,
size_t inputSize,
size_t window,
float* output,
size_t outputSize )
{
// Prevent unused warnings
(void)inputSeries ;
(void)inputSize ;
(void)window ;
// Create block to allow variables to be "shadowed"
{
// Override inputs
// NASTY HACK
const size_t inputSize = 11 ;
const int inputSeries[11] = {1, 2, 2, 3, 6, 8, 9, 2, 1, 2, 1};
const size_t window = 5 ;
int sum = 0 ;
if( inputSeries != NULL && output != 0 )
{
for( size_t i = 0; i < inputSize; i++ )
{
// Add newest sample
sum += inputSeries[i] ;
// Subtract oldest sample
if( i >= window )
{
sum -= inputSeries[i - window] ;
}
// Only write to caller output if index in bounds
if( i < outputSize )
{
output[i] = (float)sum / window ;
}
}
}
}
}
Of course you could simply change the variable names and ignore the input parameters, but if doing this in existing working code of any complexity, the above hack may be less error prone (no renaming of variables). That said, such a solution might look like:
void Array_MovingAverage( const int* inputSeries,
size_t inputSize,
size_t window,
float* output,
size_t outputSize )
{
// Prevent unused warnings
(void)inputSeries ;
(void)inputSize ;
(void)window ;
// Local "input" data
const int input[] = {1, 2, 2, 3, 6, 8, 9, 2, 1, 2, 1};
const size_t size = sizeof(input) / sizeof(*input) ;
const size_t width = 5 ;
int sum = 0 ;
if( input != NULL && output != 0 )
{
for( size_t i = 0; i < size; i++ )
{
// Add newest sample
sum += input[i] ;
// Subtract oldest sample
if( i >= window )
{
sum -= input[i - width] ;
}
// Only write to caller output if index in bounds
if( i < outputSize )
{
output[i] = (float)sum / window ;
}
}
}
}

You have lots of issues in your code:
Array_MovingAverage(const int inputSeries[], size_t inputSize, size_t window, float output[],
size_t outputSize) {
if (inputSeries && output != NULL){
for(size_t i = 0; i < window ; i++)
if (window < inputSize)
if (inputSeries != NULL && output != NULL) { << This is same as if statemend 3 lines above
if(outputSize >= inputSize) {
size_t inputSize[11] = {1, 2, 2, 3, 6, 8, 9, 2, 1, 2, 1}; //<< this hides parameter. And has totally different type.
const uint8_t window = 5; // Also hiding parameter
{
const int inputSeries[] = {1, 2, 2, 3, 6, 8, 9, 2, 1, 2,1}; // again hiding
double window = 5; // more hiding of variables and parameters
double c = 2.0; // Where does this value come from?
double d = 2.0;
for(int i = 0; i < window; i++) // Same loop variable as outer loop.
{
c += inputSeries[i];
d = c / window;
}
return true; // You return after first iteration of outer loop.
// No printf so far
// No value assigned to output[] so far.
// The only result is return value true.
}
}
}
}
}
You hide window two times with different types. Unless that is some obfuscation contest, that is a NO NO!
Also the other parameters are hidden with variables of different type.
The outer loop has no effect at all, as it will never reach second iteration.
Checking parameters inside the loop again and again (if it was executed more than once) is waste of CPU time.
Lets reorder your code a bit and remove some strange things (code not tested, whoever finds typos, may keep them. ;) )
void Array_MovingAverage(const int inputSeries[], size_t inputSize, size_t window, float output[],
size_t outputSize) {
if ( window < inputSize
&& inputSeries != NULL && output != NULL
&& outputSize >= inputSize ) {
double c = 0.0;
double avg;
int i;
// first fill partial window at begin
for (int i = 0; i < window; i++)
{
c += inputSeries[i];
avg = c / (i+1);
output[i] = avg;
}
// Then handle full windows until we reach the end
// c now contains sum of entries 0..window-1
// i points to entry 'window'
for ( ; i < inputSize; i++)
{
// Move the window by adding 1 new element and remove 1 old element
c += inputSeries[i];
c -= inputSeries[i-window]
avg = c / window;
output[i] = avg;
}
}
}
int main(void)
{
int input[] = {1, 2, 2, 3, 6, 8, 9, 2, 1, 2,1};
size_t Size = sizeof(input)/(input[0]);
float output[Size] = {0};
Array_MovingAverage(intput, Size, 5, output, Size);
printf("Moving avarage:\n");
for (int i = 0; i < Size; i++)
{
printf("%d ", input[i]);
}
for (int i = 0; i < Size; i++)
{
printf("%f ", (int)(output[i]+0.5));
}
}

Related

How do I solve this array problem in C language?

I have 2 arrays:
int element[3] = {0, 1, 2};
int quantity[3] = {2, 3, 4};
Now I want a result array that will have two zeros, three ones and four twos.
int result[2+3+4] = {0, 0, 1, 1, 1, 2, 2, 2, 2};
How do I do this using loop?
You need to count the number of elements in the result array and to declare either a variable length array with the calculated value or to allocate dynamically such an array.
For example
int quantity[3] = {2, 3, 4};
size_t n = 0;
for ( size_t i = 0; i < 3; i++ )
{
n += quantity[i];
}
int result[n];
// or
// int *result = malloc( n * sizeof( int ) );
And then in nested loops you need fill the resulted array.
For example
for ( size_t i = 0, j = 0; i < 3; i++ )
{
for ( size_t k = 0; k < quantity[i]; k++ )
{
result[j++] = element[i];
}
}
Firstly we need to calculate the size of the result array. Then start populating your result array each element at a time. While we populate the result array, we need to increment the index.
int elementSize = sizeof(element)/sizeof(element[0]);
int resultSize = 0;
//pre calculating the size of result array
for(int i=0;i<elementSize;i++ ) {
resultSize += quantity[i];
}
int result[resultSize], currIndex = 0;
//picking each element
for(int i = 0;i< elementSize; i++ ) {
int currElement = element[i];
int currQuantity = quantity[i];
//filling the current element required no of times in the result array
while(currQuantity--) {
result[currIndex] = currElement;
currIndex++;
}
}
//just a for loop to check the elements inside result array
for(int i=0;i<resultSize;i++)
printf("%d\n",result[i]);

Im trying to find the max and min value and its respective index. However I cant get the indexmin

Find the minimum element of the array and its corresponding index.
I can't get the the minimum index to work. Do I add else statement under each if statement?
#include<stdio.h>
int main()
{
int array[10]={1,2,3,4,5,6,7,8,9,10} , i;
**//finding max and min, and its respective index**
int max = array[0] , min = array[0];
int indmin , indmax;
for( i = 0 ; i < 10 ; i++ )
{
if(array[i] > max)
{
max = array[i];
indmax = i;
}
if(array[i] < min)
{
min = array[i];
indmin = i;
}
}
//print the max and min value and its indexs
printf("\nMaximum element is %d\t index is %d", max , indmax);
printf("\nMinimum element is %d\t index is %d", min , indmin);
}
Initialize indmin and indmax. When defining the array leave out the size so it's derived from the data. When iterating over the array use sizeof(array) / sizeof(*array) to let compiler determine the size of the array instead of hard-coding it. Minimize scope of variable i. Use a function to print output for less duplication:
#include <stdio.h>
void print(const char *prompt, int value, int index) {
printf("%s element is %d\t index is %d\n", prompt, value, index);
}
int main() {
int array[]={1,2,3,4,5,6,7,8,9,10};
int min = array[0];
int indmin = 0;
int max = array[0];
int indmax = 0;
for(int i = 0; i < sizeof(array) / sizeof(*array); i++) {
if(array[i] > max) {
max = array[i];
indmax = i;
}
if(array[i] < min) {
min = array[i];
indmin = i;
}
}
print("Maximum", max, indmax);
print("Minimum", min, indmin);
}
You could refactor this by creating a struct to keep the value and index together:
#include <stdio.h>
struct value_index {
int value;
int index;
};
void print(const char *prompt, struct value_index *vi) {
printf("%s element is %d\t index is %d\n", prompt, vi->value, vi->index);
}
int main() {
int array[]={1,2,3,4,5,6,7,8,9,10};
struct value_index min = { array[0], 0 };
struct value_index max = { array[0], 0 };
for(int i = 0; i < sizeof(array) / sizeof(*array); i++) {
if(array[i] > max.value) {
max.value = array[i];
max.index = i;
}
if(array[i] < min.value) {
min.value = array[i];
min.index = i;
}
}
print("Maximum", &max);
print("Minimum", &min);
}
Or you could realize that you only need the original array along with the two indices. To make my version even better than #Fe2O3's answer, I used a macro to make mine smaller (and if bait works then I will claim mine is easier to read) :-)
#include <stdio.h>
void print(const char *prompt, int *arr, int index) {
printf("%s element is %d\t index is %d\n", prompt, arr[index], index);
}
int main() {
int array[]={1,2,3,4,5,6,7,8,9,10};
int indmin = 0;
int indmax = 0;
for(int i = 0; i < sizeof(array) / sizeof(*array); i++) {
#define CMP_AND_SET(OP, V) if(array[i] OP array[V]) V = i
CMP_AND_SET(<, indmin);
CMP_AND_SET(>, indmax);
#unset CMP_AND_SET
}
print("Maximum", array, indmax);
print("Minimum", array, indmin);
}
Building on #Fe2O3's branchless idea combined with an initialized array which I find to compact and quite readable:
indmin = (int[]) { indmin, i }[array[i] < array[indmin]];
indmax = (int[]) { indmax, i }[array[i] > array[indmax]];
By using (a < b) <=> -1 * (-a > -b) you can write the last one as (note: UB if array contains INT_MIN):
indmax = (int[]) { indmax, i }[-array[i] < -array[indmax]];
I would use a local macro to reduce code duplication by using macro to generate either the first version by passing in the operator (see above) or the 2nd version by passing in a factor F:
#define MINMAX(V, F) V = (int[]) { V, i }[F * array[i] < F * array[V]]
indmin = MINMAX(indmin, 1);
indmax = MINMAX(indmax, -1);
I am totally cheating but you can shuffle the min and max elements to fixed positions within the source array. No storage overhead. This would be the opposite of branchless.
#include <stdio.h>
void print(const char *prompt, int value) {
printf("%8s = %3d\n", prompt, value);
}
int swap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
return 0;
}
int main(void) {
int arr[] = { 1, 2, 3, 4, 42, 5, -42, 6, 7, 8, 9, 10 };
const int min = 0;
const int max = sizeof arr/sizeof *arr - 1;
for(int i = 1; i < max + 1; i++ )
arr[i] < arr[min] && swap(arr + i, arr + min) ||
arr[i] > arr[max] && swap(arr + i, arr + max);
print("min", arr[min]);
print("max", arr[max]);
}
Leaving variables uninitialised is asking Demon of Hard-To-Find Bugs to co-author your code. Define variables close to where they are used to increase clarity. And, don't define more variables than you need. (Common beginner mistake to make another copy "just in case"...)
// use the spacebar to increase readability
#include <stdio.h>
int main() {
// let the compiler assign the size of an initialised array
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// use fewer variables
int indmin = 0, indmax = 0;
// don't compare an element (arr[0]) to itself
for( int i = 1 ; i < sizeof array/sizeof array[0]; i++ )
if( array[ i ] > array[ indmax ] )
indmax = i; // updated
else
if( array[ i ] < array[ indmin ] )
indmin = i; // updated
// don't add unnecessary braces (imho)
// this isn't the 17th century in need of needless filligree.
// use '\n' at the END of output. sometimes needed to 'flush' output buffer
printf("Maximum element is %d\t index is %d\n", array[ indmax ] , indmax);
printf("Minimum element is %d\t index is %d\n", array[ indmin ] , indmin);
return 0;
}
Maximum element is 10 index is 9
Minimum element is 1 index is 0
EDIT:
So, there's a friendly competition going on in this question... :-)
How's this:
#include <stdio.h>
int main() {
// let the compiler assign the size of an initialised array
// use shorter names to expose operations (not lengthy variable names)
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int iMin = 0, iMax = 0;
// don't compare an element to itself
for( int i = 1; i < sizeof arr/sizeof arr[0]; i++ ) {
// use "branchless" coding for speed.
int n = arr[i] > arr[iMax];
iMax = n*i + !n*iMax;
n = arr[i] < arr[iMin];
iMin = n*i + !n*iMin;
}
// reduce duplication of static data
char *fmt = "%s element is %d\t index is %d\n";
printf( fmt, "Maximum", arr[ iMax ], iMax );
printf( fmt, "Minimum", arr[ iMin ], iMin );
return 0;
}
Same output.
Ball's in your court #Allan :-)
EDIT:
There has been an advance on the last offering that needs to be addressed...
Here we go whole-hog, splurging-out with a third 'container' (mm[0]) to catch all those indexes that satisfy neither conditional ('<' & '>'). AND, a 4th 'container' (mm[3]) that doesn't change from being initialised to 0, the index of the 1st element. Besides being cryptic (not advised), this may-or-may-not be more expensive with its multiple array offset calculations... But, it's fun to look at...
#include <stdio.h>
int main() {
// added two elements to show 0 and nElem are not 'flukes'
// this really does find and report the min/max values
int arr[] = { 1, 2, 3, 4, 42, 5, -42, 6, 7, 8, 9, 10 };
int i, mm[1 + 2 + 1] = { 0 };
// assign 'i' to mm[ 0 or 1 or 2 ]. 0=latest, 1=max, 2=min, (3 unaffected)
for( i = 1; i < sizeof arr/sizeof arr[0]; i++ )
mm[ (arr[i] > arr[mm[1]]) + 2*(arr[i] < arr[mm[2]]) ] = i;
mm[ 0 ] = i-1; // always pick up the last index. Thanks #A Wind!
// now... this is getting silly!!
char *fmt = "%5s = %3d # arr[%d]\n";
char *type[] = { "last", "max", "min", "first" };
i = 3; do printf( fmt, type[i], arr[ mm[i] ], mm[i] ); while( --i >= 0 );
return 0;
}
first = 1 # arr[0]
min = -42 # arr[6]
max = 42 # arr[4]
last = 10 # arr[11]
Y'know... This might be interesting to try to apply to 3-way branching as is needed for binary searching; determining '<', '=' or '>'... Hmmm...
EDIT: (another variation on a theme at the suggestion of a worthy competitor :-)
#include <stdio.h>
int main() {
struct {
char *label;
int ind;
} mm[] = {
{ "last" },
{ "maximum" },
{ "minimum" },
{ "first" },
};
int i, arr[] = { 1, 2, 3, 4, 42, 5, -42, 6, 7, 8, 9, 10 };
for( i = 1; i < sizeof arr/sizeof arr[0]; i++ )
mm[ (arr[i] > arr[mm[1].ind]) + 2*(arr[i] < arr[mm[2].ind]) ].ind = i;
mm[ 0 ].ind = --i; // always pick up the last index. Thanks #A Wind!
for( i = sizeof mm/sizeof mm[0]; --i >= 0; /* space for rent */ )
printf( "%8s = %3d # arr[%d]\n", mm[i].label, arr[ mm[i].ind ], mm[i].ind );
return 0;
}
EDIT:
Trying to cover ALL the bases, here are three more ways to skin a cat
/* Minimalist */
#include <stdio.h>
int main() {
int mm[3] = { 0 },
arr[] = { 1, 2, 3, 4, 42, 5, 6, 7, 8, 9, 10 },
i = sizeof arr/sizeof arr[0];
while( --i )
mm[ 2*(arr[i] > arr[mm[2]]) + (arr[i] < arr[mm[1]]) ] = i;
char *fmt = "arr[%d] = %3d M%simum\n";
printf( fmt, mm[1], arr[mm[1]], "in" );
printf( fmt, mm[2], arr[mm[2]], "ax" );
return 0;
}
/* Recursive - for brevity, excluding the index; just reporting two values */
#include <stdio.h>
int amin( int a[], int i ) { // NB: "amin", not "main"
int j = --i ? amin( a, i ) : i;
return (a[j]<a[i])*j + (a[j] > a[i])*i;
}
int amax( int a[], int i ) {
int j = --i ? amax( a, i ) : i;
return (a[j]>a[i])*j + (a[j]<a[i])*i;
}
int main() {
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, },
sz = sizeof arr/sizeof arr[0];
char *fmt = "M%simum: %3d\n";
printf( fmt, "in", arr[ amin(arr, sz) ] );
printf( fmt, "ax", arr[ amax(arr, sz) ] );
return 0;
}
/* And, simply brute force using a library function */
#include <stdio.h>
#include <stdlib.h>
int cmp( const void *a, const void *b ) { return *(int*)a - *(int*)b; }
int main() {
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 },
sz = sizeof arr/sizeof arr[0];
qsort( arr, sz, sizeof arr[0], cmp );
char *fmt = "M%simum: %3d\n";
printf( fmt, "in", arr[ 0 ] );
printf( fmt, "ax", arr[ --sz ] ); // again, thanks to #A Wind
return 0;
}
Many ways to skin a cat.

Recursive shortest path finding in C

I want to make a program that finds the shortest path from 0x0 to the mxn point recursively and change the values of the path to '-'. '1' values in the matrix means path and '0' means wall, and I can go in all directions.
I'm very fresh, so please try to explain the details as much you can.
int startRow = 0, startColumn = 0;
char fun(char arr[][3]);
int main()
{
char matrix[3][3] = { {1,0,1},{1,1,0},{0,1,1} };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d\t", matrix[i][j]);
}
printf("\n");
}
fun(matrix);
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d\t", matrix[i][j]);
}
printf("\n");
}
return 0;
}
char fun(char arr[][3])
{
if (arr[startColumn][startRow+1] != 0)
{
arr[startColumn][startRow + 1] = '-';
return fun(arr[startColumn][startRow + 1]);
}
else
{
startRow = 0;
return fun(arr[startColumn + 1][startRow]);
}
}
The output should be like this:
Shortest path in an unweighted graph like this is typically best done with a breadth-first search, which is implemented iteratively using a queue data structure to store search state, rather than a depth-first search using a stack (such as the call stack and recursion).
If you use a stack, a search that happens to hit the goal node isn't necessarily shortest, because the path isn't extended methodically one level at a time as in BFS. Rather, the DFS explores all the way to a terminal state as soon as possible, then begins to backtrack and explore other terminal paths. None of these paths have the shortness guarantee of BFS.
The consequence of this is that with a naive recursive implementation, you will need to explore all paths before you can claim you've found the shortest one. But if your grids are small or have few paths as appears to be the case here, this shouldn't be a problem.
If you do need to optimize yet maintain the recursion, see the canonical thread Performing Breadth First Search recursively. But going forward I'll assume we're doing DFS.
The other concern is that when the graph has cycles, you need to be able to keep track of visited nodes to avoid an infinite loop. Since you seem to not mind changing characters in your grid, it should suffice that you'll never try to re-visit a cell marked '-' and you'll undo any '-' mark at the end of a recursive call in case you find a faster path to that cell in the future.
As a C-specific aside, it's best not to write function headers like char fun(char arr[][3]). The name is unclear, as is the return value, and the parameter is hard-coded to be exactly 3 columns wide. It's unrealistic to expect a client calling the function from a library to go in and edit the source code every time they want to use a different grid. Even if they did, they'd be prohibited from calling this function on multiple grid sizes in the same program. That size should be dynamic. Also, the function relies on global state, int startRow = 0, startColumn = 0; which is not thread-safe and very prone to errors. Pass all state as parameters, or at least only read global constants.
Here's a proof of concept that could still use some clean-up (repeated code, hardcoded literals). Basically, run a standard DFS to get the length of the shortest path, then run it again to populate the first path that fulfills the minimum length requirement: very much a brute-force approach.
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void ensure(bool predicate, const char *msg, unsigned int line) {
if (!predicate) {
fprintf(stderr, "%s:%d: %s\n", __FILE__, line, msg);
exit(1);
}
}
void print_grid(size_t rows, size_t cols, char **grid) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%c", grid[i][j]);
}
puts("");
}
}
void find_shortest_path_recursive(
int path_length,
int *shortest_path_length,
int y,
int x,
size_t rows,
size_t cols,
char **grid
) {
if (y < 0 || x < 0 || y >= rows ||
x >= cols || grid[y][x] != '1') {
return;
}
else if (y == rows - 1 && x == cols - 1 &&
(*shortest_path_length < 0 ||
path_length < *shortest_path_length)) {
*shortest_path_length = path_length + 1;
}
grid[y][x] = '-';
const static int dirs[][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
for (int i = 0; i < 4; i++) {
find_shortest_path_recursive(
path_length + 1,
shortest_path_length,
y + dirs[i][0],
x + dirs[i][1],
rows,
cols,
grid
);
}
grid[y][x] = '1';
}
bool set_shortest_path_recursive(
int path_length,
int shortest_path_length,
int y,
int x,
size_t rows,
size_t cols,
char **grid
) {
if (y < 0 || x < 0 || y >= rows ||
x >= cols || grid[y][x] != '1') {
return false;
}
grid[y][x] = '-';
if (y == rows - 1 && x == cols - 1 &&
path_length + 1 == shortest_path_length) {
return true;
}
const static int dirs[][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
for (int i = 0; i < 4; i++) {
if (set_shortest_path_recursive(
path_length + 1,
shortest_path_length,
y + dirs[i][0],
x + dirs[i][1],
rows,
cols,
grid
)) {
return true;
}
}
grid[y][x] = '1';
return false;
}
int set_shortest_path(size_t rows, size_t cols, char **grid) {
int shortest_path_length = -1;
find_shortest_path_recursive(
0, &shortest_path_length, 0, 0, rows, cols, grid
);
set_shortest_path_recursive(
0, shortest_path_length, 0, 0, rows, cols, grid
);
return shortest_path_length;
}
int main(void) {
size_t rows = 8;
size_t cols = 8;
char src_grid[8][8] = {
"10011110",
"10001011",
"11111010",
"00100010",
"00110110",
"11100010",
"10011110",
"11110011",
};
char **grid = malloc(sizeof(*grid) * rows);
ensure(grid, "malloc failed", __LINE__);
for (int i = 0; i < rows; i++) {
grid[i] = malloc(sizeof(grid[i]) * cols);
ensure(grid[i], "malloc failed", __LINE__);
memcpy(grid[i], src_grid[i], cols);
}
int shortest_path_length = set_shortest_path(rows, cols, grid);
print_grid(rows, cols, grid);
printf("shortest path length: %d\n", shortest_path_length);
return 0;
}
Output:
-001---0
-000-0-1
-----0-0
001000-0
001101-0
111000-0
100111-0
111100--
shortest path length: 19

How to find top 6 elements in an array in C

I am trying to find top 6 elements from an array with their ordering number.
int x=0;
for (int k = 0; k < 6; k++) //
{
for (i = 1; i <= 90; i++)
{
if (sorted[k] < holder[i] && i >= x)
{
sorted[k] = holder[i];
x = i; //
}
}
}
But this does not work. I want it to give me output like 43->7 15 ->3 etc..
Haven't written C in a while, but here is a simple solution that modifies the array in place and uses selection sort to select the k highest numbers in the array and moves them to the front. It keeps an array of indices that correspond to where the number originally was and applies the same swaps to it.
#include <stdio.h>
#define ELEMENTS 10
void main(void)
{
// example input for execution
int numbers[10] = {9,4,5,1,8,2,3,6,0,7};
// tracks ordering of indices
int indexes[10] = {0,1,2,3,4,5,6,7,8,9};
int k = 6;
int i, j;
int max, temp;
// Partial selection sort, move k max elements to front
for (i = 0; i < k; i++)
{
max = i;
// Find next max index
for (j = i+1; j < ELEMENTS; j++)
{
if (numbers[j] > numbers[max]) {
max = j;
}
}
// Swap numbers in input array
temp = numbers[i];
numbers[i] = numbers[max];
numbers[max] = temp;
// Swap indexes in tracking array
temp = indexes[i];
indexes[i] = indexes[max];
indexes[max] = temp;
}
for (i = 0; i < k; i++) {
printf("%d -> %d\n", indexes[i], numbers[i]);
}
}
And the output:
0 -> 9
4 -> 8
9 -> 7
7 -> 6
2 -> 5
1 -> 4
Here's the answer I have for you.
I would love some constructive criticism on it from anyone who can provide some.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int numbers[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int *ptrNumbers[10];
int i=0;
for(; i < 10; i++){
ptrNumbers[i] = &numbers[i]; // assign the addresses
}
int topSix[6];
int topSixIndex=0;
for(; topSixIndex < 6; topSixIndex++){
int **best = NULL; // Pointer to the pointer to the value.
int checkIndex=0;
for(; checkIndex < 10; checkIndex++){
if(ptrNumbers[checkIndex] != NULL){
if(!best){
/* best is not yet defined */
best = &ptrNumbers[checkIndex];
// best now points to the pointer for numbers[checkIndex]
}else if(*ptrNumbers[checkIndex] > **best){
// this else if statement could be attached to the main if as
// an or condition, but I've separated it for readability.
best = &ptrNumbers[checkIndex];
// best now points to the pointer for numbers[checkIndex]
}
}
}
// assign the topSix position and flag the ptrNumbers
topSix[topSixIndex] = **best;
*best = NULL;
}
// now we'll print the numbers
for(topSixIndex = 0; topSixIndex < 6; topSixIndex++){
printf("%d\n", topSix[topSixIndex]);
}
return 0;
}
Essentially the program works like this: Given an array of ten numbers, a second array is constructed to house pointers to those 10 numbers. A third array is then constructed to house the values of the top 6 numbers. A for loop is then initialized to loop 6 times to find the highest unrecorded value. When the highest value is found by looping the pointer array, the value is assigned to the next index of the top six array. Once that value is added, the pointer array's index that points to the top six value is then assigned to NULL. This acts as a flag insuring that the value will not be added again. Finally, all numbers are printed out.
After running this code, the output I received was:
9
8
7
6
5
4
Edit: as a note, the ordering number's can be stored in a second array. You would simply need to track the checkIndex of the highest value and then assign it to a second array which contained the index values.
maybe you aren't looking for a code-only answer, but this will work:
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
// return index of max element
int max_index( int* vec, int sz )
{
int idx, max, i;
if(!sz) return -1;
idx = 0;
max = vec[0];
for(i=1; i<sz; ++i)
{
if( vec[i] > max )
{
max = vec[i];
idx = i;
}
}
return idx;
}
// return indexes of N top elements
void top( int* vec, int sz, int* out_vec, int N )
{
int i, *tmp, idx;
tmp = (int*) malloc( sz*sizeof(int) );
memcpy( tmp, vec, sz*sizeof(int) );
for(i=0; i<N; ++i )
{
idx = max_index(tmp,sz);
out_vec[i]=idx;
tmp[idx] = INT_MIN;
}
free(tmp);
}
see it live here
Make an array of struct that contain data and index, then sort it and pick up first or last 6 elements to output.
Say that you are given an array numbers. Then create an array indexes with the same size as numbers in such a way that its values are equal to their indexes. Here is an illustration:
numbers = [ 1, 7, 3, 9, 2, 0 ]
indexes = [ 0, 1, 2, 3, 4, 5 ]
Sort numbers in descending order, performing the same operations on indexes. In the end, you should end up with something like this:
numbers = [ 9, 7, 3, 2, 1, 0 ]
indexes = [ 3, 1, 2, 4, 0, 5 ]
Finally, all you need to do is work with the first six elements of these arrays.
#include <stdio.h>
#define TRUE 1
#define FALSE 0
int contains(int array[], int array_size, int value)
{
int i;
for (i = 0; i < array_size; i++)
{
if (array[i] == value)
{
return TRUE;
}
}
return FALSE;
}
int main()
{
int numbers[] = { 1, 7, 3, 9, 2, 0 };
int indexes[] = { 0, 1, 2, 3, 4, 5 };
int numbers_size = 6;
int largest[] = { -1, -1, -1, -1, -1, -1 };
int largest_index = 0;
int i;
for (i = 0; i < 6; i++)
{
int j;
int max_index = -1;
int max = -2147483648;
for (j = 0; j < numbers_size; j++)
{
if (numbers[j] >= max && contains(largest, numbers_size, j) == FALSE)
{
max_index = j;
max = numbers[max_index];
}
}
largest[largest_index++] = max_index;
}
for (i = 0; i < 6; ++i)
{
printf("%d->%d\n", largest[i], numbers[largest[i]]);
}
return 0;
}
You probably should use bubblesort (and keep a function holding all the original indexes) and then just make it show the 6 first number of both arrays (from the indexes array and from the array you sorted itself)

how to find complete sorting of elements by frequency?

Here is the problem:
Given an array of integers, sort the array according to frequency of elements. For example, if the input array is {2, 3, 2, 4, 5, 12, 2, 3, 3, 3, 12}, then modify the array to {3, 3, 3, 3, 2, 2, 2, 12, 12, 4, 5}. if 2 numbers have same frequency then print the one which came 1st.
I know how to do it partially. Here is my approcach.
I will create a struct which will be like:
typedef struct node
{
int index; // for storing the position of the number in the array.
int count; // for storing the number of times the number appears
int value; // for storing the actual value
} a[50];
I will create an array of these structs, I will then sort it by a sorting algorithm on the basis of their count. However, how can I ensure that if the frequency of two elements are same, then that number should appear which has a lesser index value?
#include <stdlib.h> // qsort, malloc, free
#include <stddef.h> // size_t
#include <stdio.h> // printf
struct number
{
const int * value;
int num_occurrences;
};
static void cmp_by_val(const struct number * a, const struct number * b)
{
if (*a->value < *b->value)
return -1;
else if (*b->value < *a->value)
return 1;
else
return 0;
}
static void cmp_by_occurrence_stable(const struct number * a, const struct number * b)
{
if (a->num_occurrences < b->num_occurrences)
return -1;
else if (b->num_occurrences < a->num_occurrences)
return 1;
else if (a->value < b->value)
return -1;
else if (b->value < a->value)
return 1;
else
return 0;
}
static struct number * sort_by_occurrence(const int * arr, size_t N)
{
//
// STEP 1: Convert the input
//
struct number * sort_arr = (struct number *)malloc(N * sizeof(struct number));
if (! sort_arr) return NULL;
for (int k = 0; k < N; ++k)
{
sort_arr[k].value = &arr[k];
sort_arr[k].num_occurrences = 0;
}
//
// STEP 2: Sort the input based on value
//
qsort(sort_arr, N, sizeof(struct number), cmp_by_val);
//
// STEP 3: Count occurrences
//
if (0 < N)
{
int cur_value = *sort_arr[0].value;
int i = 0;
for (j = 1; j < N; ++j)
{
if (*sort_arr[j].value != *sort_arr[i].value)
{
for (int k = i; k < j; ++k)
sort_arr[k].num_occurrences = j - i;
i = j;
}
}
for (; i < N; ++i)
sort_arr[i].num_occurrences = N - i;
}
//
// STEP 4: Sort based on occurrence count
//
qsort(sort_arr, N, sizeof(struct number), cmp_by_occurrence_stable);
//
// DONE
//
return sort_arr;
}
static void print_arr(const struct number * arr, size_t N)
{
if (0 < N)
{
printf("%d", arr[0]->value);
for (int k = 1; k < N; ++k)
printf(", %d", arr[k]->value);
}
printf("\n");
}
int main(int argc, char ** argv)
{
const int EXAMPLE_INPUT[11] = { 2, 3, 2, 4, 5, 12, 2, 3, 3, 3, 12 };
struct number * sort_arr = sort_by_occurrence(EXAMPLE_INPUT, 11);
if (sort_arr)
{
print_arr(sort_arr, 11);
free(sort_arr);
}
};
You could create an array which stores the frequency of your input array (i.e. frequency[i] is the frequency of the input[i] element). After that it is easy to order the frequency array (using an stable algorithm) and make the same changes (swaps?) to the input array.
For creating the frequency array you can use several approaches, a simple and inefficient one is just counting each element with two nested loops. I left more efficient alternatives to your imagination.
Note: the frequency array has the same function as the count field in your struct node, but in a separated memory. If you will not need the frequencies in the future, I recommend you to use the separated memory, as you can release it.
It seems that the problem is using unstable sort algorithm on the frequency of array elements.
Do a qsort on the array based on freq
Again do a qsort on the resulted array based on the indexes of the element with the same freq only.
This should give you a correct answer in O(nLog)
I minimized the code. The obvious parts are left out.
struct node
{
int *val;
int freq;
// int index; <- we can do this by comparing &a->val with &b->val
};
int compare_byfreq(const int* a, const int* b)
{
return a->freq - b->freq;
}
int compare_index(const int* a, const int* b)
{
if( a->freq == b->freq)
{
return a->val - b->val; //this can never be zero
}
//else we have different freq don't move elem
return 0;
}
int main()
{
int arr[] = {2, 3, 2, 4, 5, 12, 2, 3, 3, 3, 12};
node *narray = (struct node*)malloc(sizeof(arr) * sizeof(node));
// build the nodes-array
for(int i =0; i < sizeof(arr); i++)
{
/* buid narray here, make sure you store the pointer to val and not the actual values */
}
qsort(narray, sizeof(arr), compare_byfreq);
qsort(narray, sizeof(arr), compare_index);
/*print narray*/
return 0;
}
Edit: #0xbe5077ed got an interesting idea. Instead of comparing indexes compare addresses of your values! - I just re-edited the code for that
I was trying to learn Java nowadays, realized that this could be a good exercise. Tried and solved this problem over there in Eclipse. Java is horrible, I went back to C to solve it, here's a solution that I'll explain right after showing it:
#include <stdio.h>
#include <malloc.h>
typedef struct numbergroup {
int firstencounteridx;
int count;
int thenumber;
} Numbergroup;
int firstoneissuperior( Numbergroup gr1, Numbergroup gr2 ) {
return gr1.count > gr2.count || // don't mind the line-break, it's just to fit
( gr1.count == gr2.count && gr1.firstencounteridx < gr2.firstencounteridx );
}
void sortgroups( Numbergroup groups[], int amount ) {
for ( int i = 1; i < amount; i++ ) {
for ( int j = 0; j < amount - i; j++ ) {
if ( firstoneissuperior( groups[j + 1], groups[j] ) ) {
Numbergroup temp = groups[j + 1];
groups[j + 1] = groups[j];
groups[j] = temp;
}
}
}
}
int main( ) {
int input[] = { 2, 3, 2, 4, 5, 12, 2, 3, 3, 3, 12 };
Numbergroup * groups = NULL;
int amountofgroups = 0;
for ( int i = 0; i < ( sizeof input / sizeof * input ); i++ ) {
int uniqueencounter = 1;
for ( int j = 0; j < amountofgroups; j++ ) {
if ( groups[j].thenumber == input[i] ) {
uniqueencounter = 0;
groups[j].count++;
break;
}
}
if ( uniqueencounter ) {
groups = realloc( groups, ( amountofgroups + 1 ) * sizeof * groups );
groups[amountofgroups].firstencounteridx = i;
groups[amountofgroups].count = 1;
groups[amountofgroups].thenumber = input[i];
amountofgroups++;
}
}
sortgroups( groups, amountofgroups );
for ( int i = 0; i < amountofgroups; i++ )
for ( int j = 0; j < groups[i].count; j++ )
printf( "%d ", groups[i].thenumber );
free( groups );
putchar( 10 );
return 0;
}
Let me explain the structure first, as well as its functionality: It is for each unique number. In your example, it is for 2s, 3s, 4s, 5s and the 12s, one for each, 5 in total. Each one is to store:
the index of the first encounter of that number
the amount of encounter of that number
the value of that number
For example, for 12s, it shall store:
firstencounteridx as 5, that is the index of the first 12
count as 2
thenumber as 12
The first loop generally does that. It expands the group of Numbergroups whenever a unique number is encountered, stores its index as well; increases the count in case a number that already has a group has been encountered.
Then a sort is issued, which simply is a bubble sort. Might be different than the conventional one, I don't have any memorized.
Sorting criteria function simply checks if the count field of the first group is greater than the other; otherwise it checks whether they are the same and the firstencounter of the first group is earlier than the other; in which cases it returns 1 as true. Those are the only possible ways for the first group to be considered superior than the second one.
That's one method, there can be others. This is just a suggestion, I hope it helps you, not just for this case, but in general.
Created a map and sort the map by value.
O(nlogn) time, and O(n) space.
import java.util.*;
public class SortByFrequency {
static void sortByFreq( int[] A ) {
// 1. create map<number, its count>
Map<Integer, Integer> map = new HashMap<>();
for(int i = 0; i < A.length; i++) {
int key = A[i];
if( map.containsKey(key) ) {
Integer count = map.get(key);
count++;
map.put(key, count);
}
else {
map.put(key, 1);
}
}
// 2. sort map by value in desc. order
// used modified (for desc. order) MapUtil in http://stackoverflow.com/questions/109383/how-to-sort-a-mapkey-value-on-the-values-in-java
Map<Integer, Integer> map2= MapUtil.sortByValue(map);
for(Map.Entry<Integer, Integer> entry : map2.entrySet() ) {
int num = entry.getKey();
int count = entry.getValue();
for(int i = 0; i < count; i++ ) {
System.out.print( num + " ");
}
}
System.out.println();
}
public static void main(String[] args ) {
int[] A1 = {2, 3, 2, 4, 5, 12, 2, 3, 3, 3, 12};
sortByFreq(A1);
}
}

Resources