Reputation: 43
Hi Community of Coders/Programmers,
I am trying to solve a problem having mix of everything, from sorting to using array, to finding length of array.
I'm trying to figure out median of numbers input in an array of strings, then converted to int array. Even array and odd array both have a different median.
While dry-running, I enter array as 1,2,3,4,5,6,7
and then press Enter. But the result I get is 0
. What could be the error in debugging it, any variable which is left uninitialised?
Thanks.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TRUE 1;
#define FALSE 0;
int arrayeven_median(int[], int);
int arrayodd_median(int[], int);
int stringlen(char[]);
int *sort(int[], int);
int num[100];
char numbers[100];
char string[100];
int sortednum[100];
int main()
{
printf("Enter array of numbers separated by comma\n");
gets(numbers);
char *pt;
/* get the first token */
pt = strtok(numbers, ",");
/* walk through other tokens */
while (pt != NULL)
{
int i = 0;
num[i] = atoi(pt);
sortednum[i] = *sort(&num[i], stringlen(numbers));
pt = strtok(NULL, ",");
i++;
}
if (stringlen(numbers) % 2 == 0)
printf("%d", arrayeven_median(sortednum, stringlen(numbers)));
else
printf("%d", arrayodd_median(sortednum, stringlen(numbers)));
return 0;
}
int stringlen(char string[])
{
int i;
for (i = 0; string[i] != '\0'; i++)
;
return i;
}
int *sort(int x[], int n)
{
int hold, j, pass;
int switched = TRUE
;
for (pass = 0; pass < n - 1; pass++)
{
switched = FALSE
;
for (j = 0; j < n - pass - 1; j++)
if (x[j] > x[j + 1])
{
switched = TRUE
;
hold = x[j];
x[j] = x[j + 1];
x[j + 1] = hold;
}
}
return x;
}
int arrayeven_median(int x[], int n)
{
int m1 = n / 2;
int m2 = (n / 2) + 1;
int median = (x[m1] + x[m2]) / 2;
return median;
}
int arrayodd_median(int x[], int n)
{
int m1 = (n / 2) + 1;
int median = x[m1];
return median;
}
Upvotes: 1
Views: 243
Reputation: 43
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TRUE 1
#define FALSE 0
int arrayeven_median(int *, int);
int arrayodd_median(int *, int);
int *sort(int[], int);
int num[100];
char numbers[100];
char string[100];
int index1;
int main()
{
printf("Enter array of numbers separated by comma\n");
if (!fgets(numbers, sizeof numbers, stdin)) {
printf("no input\n");
return 0;
}
char *pt;
/* get the first token */
pt = strtok(numbers, ",");
int i = 0;
/* walk through other tokens */
while (pt != NULL)
{
num[i] = atoi(pt);
pt = strtok(NULL, ",");
i++;
if(pt == NULL)
index1 = i;
}
if (index1 % 2 == 0)
printf("%d", arrayeven_median(sort(num, index1), index1));
else
printf("%d", arrayodd_median(sort(num, index1), index1));
return 0;
}
int *sort(int x[], int n)
{
int hold, j, pass;
int switched = TRUE;
for (pass = 0; pass < n - 1; pass++)
{
switched = FALSE;
for (j = 0; j < n - pass - 1; j++)
if (x[j] > x[j + 1])
{
switched = TRUE;
hold = x[j];
x[j] = x[j + 1];
x[j + 1] = hold;
}
}
return x;
}
int arrayeven_median(int *x, int n)
{
int m1 = n / 2;
int m2 = (n / 2) + 1;
printf("%d\n", m1);
int median = (x[m1-1] + x[m2-1]) / 2;
return median;
}
int arrayodd_median(int *x, int n)
{
int m1 = (n/2) + 1;
int median = x[m1-1];
return median;
}
Upvotes: 0
Reputation: 144780
There are problems in your code:
You keep storing the converted number to the first element of the array. i
should be initialized outside the while
loop.
sortednum[i] = *sort(&num[i], stringlen(numbers));
makes no sense: stringlen(numbers)
computes the length of the input string in characters, yet this input string was truncated by strtok()
and it is irrelevant for the sort
function anyway that expects the number of elements in the int
array. You should instead store the value at the end of the int
array and sort this array once all values have been stored.
#define TRUE 1;
is incorrect: TRUE
will expand to 1;
instead of 1
, potentially causing syntax errors.
the sort
function does not use the switched
flag to break early from the outer loop if the array is sorted.
function gets()
has been removed from the C standard because it cannot be used safely as it is not given the size of the destination array. Use fgets()
instead.
The arrays should be defined local to the main
function, unless they are very large and should then be allocated.
arrayodd_median()
does not return the median element. It even accesses beyond the boundaries of the array if n == 1
.
you should test for invalid or incomplete input.
Here is a corrected version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TRUE 1
#define FALSE 0
int arrayeven_median(int[], int);
int arrayodd_median(int[], int);
void sort(int[], int);
int main(void) {
char numbers[100];
int num[100];
int i;
char *pt;
printf("Enter array of numbers separated by comma\n");
if (!fgets(numbers, sizeof numbers, stdin)) {
printf("no input\n");
return 0;
}
/* get the first token */
pt = strtok(numbers, ", \n");
if (pt == NULL) {
printf("no numbers\n");
return 0;
}
/* walk through all tokens */
for (i = 0; i < 100 && pt != NULL; i++) {
/* convert the token string to an `int` and store at the end of the array */
num[i] = atoi(pt);
/* parse the next token */
pt = strtok(NULL, ", \n");
}
/* sort the int array in place */
sort(num, i);
if (i % 2 == 0) {
/* array length is even, find the median value */
printf("%d\n", arrayeven_median(num, i));
} else {
/* array length is odd, find the median element */
printf("%d\n", arrayodd_median(num, i));
}
return 0;
}
void sort(int x[], int n) {
int hold, j, pass;
for (pass = 0; pass < n - 1; pass++) {
int switched = FALSE;
for (j = 0; j < n - pass - 1; j++) {
if (x[j] > x[j + 1]) {
switched = TRUE;
hold = x[j];
x[j] = x[j + 1];
x[j + 1] = hold;
}
}
if (!switched) {
break out of the loop if the rest of the array is sorted */
break;
}
}
}
int arrayeven_median(int x[], int n) {
int m = n / 2;
return (x[m] + x[m + 1]) / 2;
}
int arrayodd_median(int x[], int n) {
return x[n / 2];
}
Notes:
atoi
does not handle overflow: passing a string that represents very large numbers may cause unexpected behavior.arrayeven_median
has a potential arithmetic overflow: on 32-bit systems, it will produce an incorrect result for input 2147483647,2147483647
Upvotes: 4