1

I was trying to write a function that checks if an array has consecutive numbers (not necessarily in order), return 0 if not and 1 if yes.

For example:

24, 21, 22, 23 

The return value would be 1.

22,22,22 

Would return 0.

The problem is that it return 1 for something like:

22,22,22 

I could really use the help looking into it.

This is the main function (no need to check it or anything, it's fine):

#include <stdio.h> #include <stdlib.h> /* Function declarations */ void Ex1(); void Ex2(); void Ex3(); void Ex4(); void Ex5(); /* Declarations of other functions */ int f3(int *, int); /* ------------------------------- */ // int main() { int select = 0, i, all_Ex_in_loop = 0; printf("Run menu once or cyclically?\n" "(Once - enter 0, cyclically - enter other number) "); if (scanf_s("%d", &all_Ex_in_loop) == 1) do { for (i = 1; i <= 5; i++) printf("Ex%d--->%d\n", i, i); printf("EXIT-->0\n"); do { select = 0; printf("please select 0-5 : "); scanf_s("%d", &select); } while ((select < 0) || (select > 5)); switch (select) { case 1: Ex1(); break; case 2: Ex2(); break; case 3: Ex3(); break; case 4: Ex4(); break; case 5: Ex5(); break; } } while (all_Ex_in_loop && select); return 0; } 

and this is the function (UPDATED):

void Ex3() { int n, i, res; printf("Enter the size of the Array: "); scanf_s("%d", &n); int *arr = (int *)malloc(n * sizeof(int)); if (!arr) { printf("ERROR - not enough memory."); exit(1); } printf("Enter an Array >>> "); for (i = 0; i < n; i++) scanf_s("%d", &arr[i]); res = f3(arr, n); printf("res = %d\n", res); free(arr); } int f3(int *arr, int size) { int i, min = arr[0], max = arr[0]; for (i = 1; i < size; i++) { if (arr[i] < min) min = arr[i]; if (arr[i] > max) max = arr[i]; } int *CounterArray = (int *)calloc(max + 1, sizeof(int)); if (!CounterArray) { printf("ERROR - not enough memory."); exit(1); } for (i = 0; i < size; i++) { CounterArray[arr[i]]++; } for (i = min; i <= max; i++) if (CounterArray[i] == 0) return 0; free(CounterArray); return 1; } 
11
  • 4
    You have free function call after return statement. Commented Jan 11, 2021 at 18:22
  • You can sort the input array and then test for the consecutive predicate. Commented Jan 11, 2021 at 18:24
  • Please read about how to create an MCVE (Minimal, Complete, Verifiable Example — or MRE or whatever name SO now uses) or an SSCCE (Short, Self-Contained, Correct Example). Most of the code in main() is irrelevant — you only need a single call Ex3() in it. Commented Jan 11, 2021 at 18:24
  • Are negative numbers allowed in the array? Commented Jan 11, 2021 at 18:25
  • 2
    In function f3() you break the array bounds with for (i = 1; i <= size; i++) OK you set the min and max from element [0] but the upper bound breaks. Commented Jan 11, 2021 at 18:26

2 Answers 2

1

There are multiple problems in your code:

  • in function f3() you allocate an array of max + 1 integers. This would be a problem is all numbers in the array are negative. You should instead check that max - min + 1 is exactly the size of the array and allocate size elements.
  • you reject the array if and only if an element in the range has a 0 count. You should instead check that all elements have a 1 count. This explains why the function fails for 22,22,22.

Here is a modified version:

int f3(const int *arr, int size) { int result = 1; if (size <= 0) return 1; int i, min = arr[0], max = arr[0]; for (i = 1; i < size; i++) { if (min > arr[i]) min = arr[i]; if (max < arr[i]) max = arr[i]; } if (max - min + 1 != size) return 0; unsigned char *CounterArray = calloc(size, sizeof(*CounterArray)); if (!CounterArray) { printf("ERROR - not enough memory."); exit(1); } for (i = 0; i < size; i++) { // increment the count of this element if (CounterArray[arr[i] - min]++) { // if the count was already non zero, the test fails. result = 0; break; } } free(CounterArray); return result; } 
Sign up to request clarification or add additional context in comments.

5 Comments

@4386427: The numbers need not be in any particular order. The second loop counts the occurrences of all numbers in the array, the third checks that all numbers between min and max inclusive have a count of 1. size is also the value of max - min + 1 as checked before allocating the array.
For all consecutive numbers between min and max to be present once in the array, its size must be max - min + 1 :) The array is only allocated for cases like 0,0,3,3.
@4386427: the OP is pretty clear about that: I was trying to write a function that checks if an array has consecutive numbers (not necessarily in order)
I deleted my own answer and my comments here as I probably misunderstood the question. A little suggestion for your solution: The if (CounterArray[i] != 1) ..... in the last loop can be moved into the loop above, i.e. just after CounterArray[arr[i] - min]++;. Then the last loop can be deleted.
@4386427: good point! I was pondering about that and did not realise it would make the last loop useless. Thanks for the edit too. The array type can be smaller too.
0

You return zero under the condition that

if (CounterArray[i] == 0) 

but in your test case of 22,22,22 you have min and max both equal 22 and CounterArray[22] equal 3, not 0.

You need to re-think the condition...

Comments