1

I am new to coding in C. I am trying to write a code that finds the peak number in an array, that is the numbers that are greater than the numbers before and after said number.

This is my code. It runs without error but no output so I know I am doing something wrong.

#include <stdio.h>
int main() {
 int nums[14] = {1, 2, 3, 3, 2, 4, 1, 5, 6, 3, 1, 10, 2, 8};
  int peaks[4];

 for(int i = 0; i < nums[i]; i++){
     if(nums[i] > nums[i-1] && nums[i] > nums[i+1]){
         peaks == nums[i];
     }
     return peaks;
 }

 printf("Peak numbers are %d",peaks);
}

How can I get it to output this as the result: [4, 6, 10, 8]

Ajay Brahmakshatriya
  • 8,993
  • 3
  • 26
  • 49
lenany
  • 75
  • 1
  • 2
  • 8
  • 2
    `peaks == nums[i];` your compiler did not shout? – Sourav Ghosh Aug 31 '17 at 07:20
  • 3
    Your loop condition, are you *sure* about it? It will stop after the third element of `nums`. – Some programmer dude Aug 31 '17 at 07:21
  • 4
    There are also many other problems, like you how try to print the peak numbers, using comparison instead of assignment, not assigning to a specific element of `peaks`, and worst of all you going out of bounds of your `nums` array. You should probably get a few [good beginners books](https://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list) and start over from the beginning. – Some programmer dude Aug 31 '17 at 07:24
  • 1
    The stop condition of the for loop is incorrect. You want to loop over the entire array (almost). You also need special treatment of the first and last element or you will read outside the array. – Klas Lindbäck Aug 31 '17 at 07:30
  • @lenany Please do not edit the question with the correct version. It is misleading for future users. – Ajay Brahmakshatriya Aug 31 '17 at 08:28
  • the posted code does not compile. When compiling, always enable all the warnings, then fix those warnings. – user3629249 Sep 01 '17 at 02:11

4 Answers4

5

Enable your compiler's warnigs!!! You should get something like this:

prog.c: In function 'main':
prog.c:8:16: warning: comparison between pointer and integer
          peaks == nums[i];
                ^~
prog.c:8:16: warning: statement with no effect [-Wunused-value]
          peaks == nums[i];
          ~~~~~~^~~~~~~~~~
prog.c:10:13: warning: returning 'int *' from a function with return type 'int' makes integer from pointer without a cast [-Wint-conversion]
      return peaks;
             ^~~~~
prog.c:10:13: warning: function returns address of local variable [-Wreturn-local-addr]
prog.c:13:28: warning: format '%d' expects argument of type 'int', but argument 2 has type 'int *' [-Wformat=]
  printf("Peak numbers are %d",peaks);
                           ~^  ~~~~~
                           %ls

So, change this:

 peaks == nums[i];

to this:

 peaks[j] = nums[i];

where j is another counter you could use.

Then you return peaks, why? It's not a custom function, so you shouldn't return.

Moreover, you try to print an array like:

printf("Peak numbers are %d",peaks);

which is not possible, you need to loop over the elements of the array, like this:

for(i = 0; i < 4; ++i)
    printf("%d\n", peaks[i]);

After correcting your warnings, you are ready to actually work on yuor logic. Your for loop will not iterate over all numbers of the array. So change this:

for(i = 0; i < nums[i]; i++)

to this:

for(i = 0; i < 14; i++)

Moreover your if statement will cause Undefined Behavior:

if(nums[i] > nums[i-1] && nums[i] > nums[i+1])

when i is 0 and when i is 13.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • With this for-loop you will access some elements outside of your array because of the `nums[i-1]` and `nums[i+1]` – izlin Aug 31 '17 at 07:32
  • @izlin yes, but in your (nice in general) answer, you won't see all the elemtents, I think. Thanks for the upvote! (still working on my answer). – gsamaras Aug 31 '17 at 07:33
  • 1
    You are right. I don't know if they fulfill the requirement that both neighbors should be higher since they have only one. Pretty nice answer anyway. – izlin Aug 31 '17 at 07:39
  • 3
    @izlin the OP's desired out put is `4, 6, 10, 8`, so 8 __is__ a peak. – Jabberwocky Aug 31 '17 at 07:43
  • Why do you initialize `peaks` with `{nums[0], nums[1], nums[2], nums[13]` ? This is useless and even worse: it makes you believe that your program works correctly, but it doesn't. – Jabberwocky Aug 31 '17 at 07:54
3

Here you have a corrected version of the program, your mistakes are in the comments:

#include <stdio.h>
int main() {
  int nums[14] = {1, 2, 3, 3, 2, 4, 1, 5, 6, 3, 1, 10, 2, 8};
  int peaks[4];
  int ctr=0;          // counter to count the amount of peaks

  for(int i = 1; i < 13; i++){   // start with one and end with 12, so you don't access elements outside of your array (-1 and 14)
                                 // You need to implement special cases for the first and the last element
    if(nums[i] > nums[i-1] && nums[i] > nums[i+1]){
      peaks[ctr] = nums[i];   // use an assignment instead of a comparison
      ctr++;                  // increment counter
    }
                              // No return here, it will end your main and the print will never be reached
  }

  printf("Peak numbers are ");
  for(int i = 0; i<ctr; i++)
    printf("%d ", peaks[i]);   // Print all the peaks you found, you need to print every element separate 

  return 0;  // main needs a return value
}

Try it online

I am trying to write a code that finds the peak number in an array, that is the numbers that are greater than the numbers before and after said number

I think the first and the last number can't fulfill this requirement, because they have only one neighbor.

izlin
  • 2,129
  • 24
  • 30
1

This program works for any number of elements in the nums array and it takes into account the first and the last element correctly.

[sizeof(nums)/sizeof(nums[0]) is the actual number of elements in the nums array, therefore yolu can put any number of elements into the nums array and the program will always work correctly

Also the number of elements of peaks is no longer hard coded as 4 but the same as the number of elements in num, so we can insure that there won't be any index out of bounds problems. However as the maximum number of peaks of an array of size n is n/2 + 1 (not quite sure), we can probably write int peaks[sizeof(nums)/sizeof(nums[0])/2+1]

#include <stdio.h>

int main() {
  int nums[] = { 1, 2, 3, 3, 2, 4, 1, 5, 6, 3, 1, 10, 2, 8 };
  int peaks[sizeof(nums)/sizeof(nums[0])];
  int pi = 0;

  for (int i = 0; i < sizeof(nums)/sizeof(nums[0]); i++) {
    if (
        (i == 0 && nums[i + 1] < nums[i]) ||   /* first element */
        (i == sizeof(nums) / sizeof(nums[0]) && nums[i - 1] < nums[i]) || /* last element */
        (nums[i] > nums[i - 1] && nums[i] > nums[i + 1]) /* elements in the middle */
      )
    {
      peaks[pi++] = nums[i];
    }
  }

  for (int i = 0; i < pi; i++)
    printf("%d ", peaks[i]);
}

However the condition in the if statement can possibly be written in a more elegant manner.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • @PatrickTrentin sure that would make more sense, but that was not the requirement of the OP. – Jabberwocky Aug 31 '17 at 08:55
  • Please, note that in your `if` condition, the *last element* part (`i == sizeof...`) is off by one (and never occurred) and for the *elements in the middle*, you are not really preventing an out of bounds access (i.e. if `i == 0`, but `nums[1] >= nums[0]`, `nums[i - 1]` is called). – Bob__ Aug 31 '17 at 11:34
-1

bro write printf statement in if loop printf("%d",peak) or remove comparison operator ==in single = from peak==array[i] beacuse you are not comaring peak with them you are assigning value of array to peak when your condition satisfied