Home > Software design >  Finding peaks on C
Finding peaks on C

Time:05-11

Write C code to initialize an array of 10 integers. If both sides of a number are smaller than it, then that number is the peak. Once you have all the peaks, create an array, store all the peaks in this new array and print them. The first question is I do not know how many peaks it may have, how to create the array to store peaks?

#include <stdio.h>
int main(void) {
    int vals[10] = {1,2,3,1,4,6,3,8,9,1}; // initialize an array of 10 integers
    int length = sizeof(vals) / sizeof(vals[0]);
    int peaks;
    for (int i = 1; i < length-1; i  ) {
       if (vals[i] > vals[i-1] && vals[i 1]) { // If both sides of a number are smaller than it
       peaks[i] = vals[i];
    }
    printf("%d",peaks[i]);
    return 0;
}

CodePudding user response:

Just create an array the same size as the vals array. It's guaranteed that the number of peaks cannot be larger than the number of values. In reality the former will be much smaller than the latter as not every value can be a peak.

But, allowing for ten will be more thn enough, without too much wastage.

Then you just use a variable to dictate how many peaks there are. For example, initialise the peak array as:

int peak[10];
size_t num_peaks = 0;

To add a peak to that array:

peak[num_peaks  ] = new_peak;

And to process the peaks:

for (size_t peak_idx = 0; peak_idx < num_peaks;   peak_idx)
    do_something_with(peak[peak_idx]);

And, a couple of things to keep in mind:

  • Should you consider the first element to be a peak if the second is lower?
  • Ditto for the final element if the penultimate one is lower.
  • How do you handle plateaus (like 1, 3, 3, 2)? Neither of those 3 values are considered a peak under your current definition since the elements on either side are not both lower.

CodePudding user response:

You were so close. You set you loop limits correctly to allow you to check both sides of the current index in the vals[] array. By looping from 1 to length - 1 you can check the values at vals[i-1] and vals[i 1] each iteration. Neither end value can be a peak as there is no value on the opposite side to check.

However, after setting up your loop, you didn't check each side of vals[i] to determine if the current value was a peak. You need to do:

  /* loop from 1 to length-1 checking value each side of current index */
  for (int i = 1; i < length - 1; i  ) {
    if (vals[i-1] < vals[i] && vals[i] > vals[i 1]) { /* if peak */
      ...

Once you determine it is a peak, simply add vals[i] as the next element in the peaks[] array, e.g.

    ...
    if (vals[i-1] < vals[i] && vals[i] > vals[i 1]) { /* if peak */
      peaks[npeaks] = vals[i];              /* add value to peaks array */
      npeaks  = 1;                          /* increment no. of peaks */
    }
  }

A short example showing the complete program would be:

#include <stdio.h>

int main (void) {
  
  int vals[] = {1,2,3,1,4,6,3,8,9,1},
      length = sizeof vals / sizeof *vals,
      peaks[sizeof vals] = {0},             /* create peaks array */
      npeaks = 0;                           /* no. of peaks found */
  
  /* loop from 1 to length-1 checking value each side of current index */
  for (int i = 1; i < length - 1; i  ) {
    if (vals[i-1] < vals[i] && vals[i] > vals[i 1]) { /* if peak */
      peaks[npeaks] = vals[i];              /* add value to peaks array */
      npeaks  = 1;                          /* increment no. of peaks */
    }
  }
  
  puts ("peaks:");                          /* output result */
  for (int i = 0; i < npeaks; i  ) {
    printf ("  peaks[%d] : %d\n", i, peaks[i]);
  }
}

(note: when using sizeof with an expression, it is generally just sizeof expression, when using with a type (such as int), then it is generally sizeof(type), but note compilers will generally accept either. See C11 Standard - 6.5.3 Unary operators)

Example Use/Output

$ ./bin/arrpeaks
peaks:
  peaks[0] : 3
  peaks[1] : 6
  peaks[2] : 9

CodePudding user response:

you can use this function to find the index of peak in an array and then you can print accordingly.

Using Binary Search.

int findPeakElement(int* nums, int numsSize) {
if(numsSize<=1) return 0;

int left=0;int right=numsSize-1;
int mid;
while(left!=right){
    if(nums[left]>nums[left 1]) {
        right=left;break;
    }
    else left =1;
    if(nums[right]>nums[right-1]){
        left=right;break;
    }
    else right-=1;
    mid=(right-left)/2 left;
    if(nums[mid]<nums[mid 1])left=mid 1;
    else right=mid;
}
return left;
}
  •  Tags:  
  • c
  • Related