C - Longest subarray of specified elements from given array - c

I need help with the following problem:
Given an array arr of structs
typedef struct
{
char name[20];
float amount,price;
}product;
Print the longest subarray of elements from array arr such that the arr element has greater or equal price than some value which is read.
Function to check if element has greater or equal price than a value is given as an argument of a function void subarray(product *arr,int n,int (*check)(product * ,float ),
product *newArr,int *len_newArr,float value)
where newArr is the output subarray.
Here is my code:
#include<stdio.h>
#include<stdlib.h>
typedef struct
{
char name[20];
float amount,price;
}product;
void subarray(product *arr,int n,int (*check)(product * ,float ),
product *newArr,int *len_newArr,float value)
{
len_newArr=0;
int *current_len;
current_len=0;
int i;
for(i=0;i<n;i++)
{
//if condition is true, increment current length of newArr
//and store that element to newArr
if((*check)(arr+i,value))
{
current_len++;
newArr[i]=arr[i];
}
else
//begin with the next subarray
current_len=1;
//update newArr length
if(current_len > len_newArr)
len_newArr=current_len;
}
newArr=calloc(*len_newArr , sizeof(product));
//print the subarray
for(i=0;i<len_newArr;i++)
printf("%-19s %6.2f %6.2f\n",newArr[i].name,newArr[i].amount,newArr[i].price);
}
int check(product *pr,float value)
{
if(pr->price >= value)
return 1;
return 0;
}
void inputProduct(product *pr)
{
printf("name: ");
scanf("%s",pr->name);
printf("amount: ");
scanf("%f",&pr->amount);
printf("price: ");
scanf("%f",&pr->price);
}
int main()
{
int n,i;
product *arr,*newArr;
int len_newArr;
float value;
do
{
printf("n = ");
scanf("%d",&n);
}
while(n<1);
arr=malloc(n * sizeof(product));
newArr=calloc(n,sizeof(product));
for(i=0;i<n;i++)
{
printf("%d. product: \n",i+1);
inputProduct(arr+i);
}
printf("value: ");
scanf("%f",&value);
subarray(arr,n,&check,newArr,&len_newArr,value);
return 0;
}
The program gives warnings assignment makes pointer from integer without a cast at line
//begin with the next subarray
current_len=1;
and comparison between pointer and integer at line
//print the subarray
for(i=0;i<len_newArr;i++)
printf("%-19s %6.2f %6.2f\n",newArr[i].name,newArr[i].amount,newArr[i].price);

int *current_len=0; /* assigining NULL to a pointer to int */
This
*current_len++;
Is equivalent to *NULL++ and you can not dereference a pointer to NULL. [More info]
Same here:
*current_len=1;
It seems that you want a plain int instead of a pointer to int

Related

Not able to find my segmentation fault in this code of t-test

I have written this program for t-test. I'll add other functions as well, but first, I need to find my error. Here's my code
# include <stdio.h>
# include <math.h>
float mean(float x[], int size)
{
float sum = 0.0;
for (int i=0; i<size;i++)
sum += x[i];
return sum/size;
}
float sumsq(float x[], int size)
{
float sum = 0.0;
for (int i=0; i<size;i++)
sum += pow(x[i]-mean(x,size),2);
return sum;
}
int input(n)
{
float x[n];
printf("Enter the values one by one");
for (int i = 0; i<n;i++)
scanf("%f", &x[i]);
return x;
}
void t_check(float x)// Make sure to write this function before each of the t-tests. That is because it is of void type. If the t-test is done before the checking function is declared, then it assumes it's datatype to be "int", and we get an error. So either write the t-check function before those functions, or just define it at the beginning of the program
{
float t_tab;
printf("Enter the tabulated value of t");
scanf("%f",&t_tab);
if (x<t_tab)
printf("We do not have enough evidence to reject the null hypothesis");
else
printf("Reject the null hypothesis");
}
float t_diff_of_means()
{
float x=0.0,y=0.0,s1=0.0,s2=0.0,S=0.0,t=0.0,tcal;
int n,m,a,b;
printf("Enter the number of variables in population 1");
scanf("%d", &n);
a = input(n);
printf("Enter the number of variables in population 2");
scanf("%d", &m);
b = input(m);
x = mean(a,n);
y = mean(b,m);
s1 = sumsq(a, n);
s2 = sumsq(b, m);
S = sqrt((s1+s2)/(n+m-2));
t = (x-y)/(S*sqrt(1.0/n+1.0/m));
t_check(t);
}
int main(void)
{
t_diff_of_means();
return 0;
}
It gives segmentation fault as an error. I'm not able to understand where my code uses any memory uses a part of memory that is not allocated to it
The main issue is you expect input() to read an array floats but you return an int. You should declare the type of the argument n. You cannot return an address to a local variable as it out of scope for caller. The easiest option is to the declare the array variable in main() then pass it to input to populate (pun). (not fixed) Check that return value of scanf() otherwise the variable you expect to be initialized may not be.
t_diff_of_means() is declared to return a float but nothing is returned. Not sure what you want to return so I changed the return type to void.
Tweaked various prompts to make it more them more readable.
#include <stdio.h>
#include <math.h>
float mean(float x[], int size)
{
float sum = 0.0;
for (int i=0; i<size;i++)
sum += x[i];
return sum/size;
}
float sumsq(float x[], int size)
{
float sum = 0.0;
for (int i=0; i<size;i++)
sum += pow(x[i]-mean(x,size),2);
return sum;
}
void input(size_t n, float a[n])
{
printf("Enter the values one by one: ");
for (int i = 0; i<n;i++)
scanf("%f", a+i);
}
void t_check(float x)
{
float t_tab;
printf("Enter the tabulated value of t: ");
scanf("%f",&t_tab);
if (x<t_tab)
printf("We do not have enough evidence to reject the null hypothesis\n");
else
printf("Reject the null hypothesis\n");
}
void t_diff_of_means()
{
float x=0.0,y=0.0,s1=0.0,s2=0.0,S=0.0,t=0.0;
int n,m;
printf("Enter the number of variables in population 1: ");
scanf("%d", &n);
float a[n];
input(n, a);
printf("Enter the number of variables in population 2: ");
scanf("%d", &m);
float b[m];
input(m, b);
x = mean(a,n);
y = mean(b,m);
s1 = sumsq(a, n);
s2 = sumsq(b, m);
S = sqrt((s1+s2)/(n+m-2));
t = (x-y)/(S*sqrt(1.0/n+1.0/m));
t_check(t);
}
int main(void)
{
t_diff_of_means();
return 0;
}
and example run:
Enter the number of variables in population 1: 2
Enter the values one by one: 1
2
Enter the number of variables in population 2: 2
Enter the values one by one: 2
3
Enter the tabulated value of t: 0.05
We do not have enough evidence to reject the null hypothesis
Consider eliminating the variables you only use once (x, y, s1, s2, S, t and t_cal):
t_check(
(mean(a, n) - mean(b, m)) / (sqrt((sumsq(a, n)+sumsq(b, m))/(n+m-2))*sqrt(1.0/n+1.0/m))
);
then I observed that this only depends on variables a, n, b and m so push that calculation into t_check():
void t_check(size_t a_len, float a[a_len], size_t b_len, float b[b_len]) {
float t = (mean(a, a_len) - mean(b, b_len)) / (sqrt((sumsq(a, a_len)+sumsq(b, b_len))/(a_len+b_len-2))*sqrt(1.0/a_len+1.0/b_len));
// ...
}
Then I changed the length types to size_t and used the clearer variable names in t_diff_of_means():
void t_diff_of_means()
{
printf("Enter the number of variables in population 1: ");
size_t a_len;
scanf("%zu", &a_len);
float a[a_len];
input(a_len, a);
printf("Enter the number of variables in population 2: ");
size_t b_len;
scanf("%zu", &b_len);
float b[b_len];
input(b_len, b);
t_check(a_len, a, b_len, b);
}
We could take this another step by observing the two first sections in t_diff_of_means() are very similar, so we could have input() take a prompt and a pointer to an array of floats along with elements read. input() would then need to dynamically allocate the array of floats. This means most of our functions take a array of float and length argument. Let's create a type for that and refactor our functions to use it:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct array {
size_t len;
float *data;
};
float mean(struct array *a)
{
float sum = 0;
for (int i=0; i<a->len;i++)
sum += a->data[i];
return sum/a->len;
}
float sumsq(struct array *a)
{
float sum = 0;
for (int i=0; i<a->len;i++)
sum += pow(a->data[i] - mean(a), 2);
return sum;
}
void input(int prompt, struct array *a)
{
printf("Enter the number of variables in population %d: ", prompt);
scanf("%zu", &a->len);
a->data = malloc(a->len * sizeof(a->data[0]));
//if(!a->data) ...
printf("Enter the values one by one: ");
for (int i = 0; i<a->len;i++)
scanf("%f", &a->data[i]);
}
void t_check(struct array a[2])
{
float t = (mean(a) - mean(a+1)) / (
sqrt(
(sumsq(a) + sumsq(a+1)) / (a[0].len + a[1].len-2)
) * sqrt(1.0/a[0].len + 1.0/a[1].len)
);
printf("Enter the tabulated value of t: ");
float t_tab;
scanf("%f",&t_tab);
if (t<t_tab)
printf("We do not have enough evidence to reject the null hypothesis\n");
else
printf("Reject the null hypothesis\n");
}
int main(void)
{
struct array a[2];
input(1, a);
input(2, a+1);
t_check(a);
}
This would be a good base to add additional functions to.

C programming parameters

#include <stdio.h>
void getScores(int a, char n[10][15], int s[10]) {
int score;
printf("Enter the number of students: ");
scanf("%d",&a);
for (int i=0; i < a;i++)
{
scanf("%s",n[i]);
scanf("%d",&score);
s[i]=score;
}
}
void printScores(int a, char n[10][15], int s[10] ) {
for (int i=0; i < a;i++)
{
printf("%s", n[a]);
printf(" ");
printf("%d\n",s[a]);
}
}
int main() {
char names[10][15];
int scores[10];
int num;
getScores(num,names,scores);
printScores(num,names,scores);
}
What I am trying to accomplish is have the parameter value of int a from the getScores function to be used in the printScores function as an array length as it is being used in getScores.
The arrays are saving its value when used in the print function but the a value is resetting to an unassigned number 896 when I need it to be what the user enters in the get function. Any tips?
Print scores will not print anything.
void getScores(int *a,
And the call
getScores(&num
You need also change accordingly the functions code

Error finding a range of values in an array

The program "reads" non negative integers and fills an array of MAX size 100 until it is filled or the user gives -1.Then, function range finds the min and max values and "sends" them to the program.For example,if the user gives 67 54 78 85 -1 the range of values is 54-85.
Problem is, main doesn't print the range. Instead, it prints: "The range of values is 2 - 24576000"
#include <stdio.h>
#include "simpio.h"
int read_data(int A[]);
void range(int sum,int A[100], int *r1, int *r2);
int main()
{
int A[100], sum, max, min,i;
int *r1,*r2;
r1 = &max;
r2 = &min;
printf("Enter the elements of the array, one per line.\n");
printf("Use -1 to signal the end of the list.\n");
sum=read_data(A);
range(sum,A, &max, &min);
printf("The number of elements is: %d\n",sum);
printf("The range of values is %d - %d",min ,max);
}
int read_data(int A[])
{
int i,sum,value;
sum=value=i=0;
while ( i<100 && value !=-1)
{
printf("? ");
value = GetInteger();
if (value != -1)
{
A[i] = value;
value = A[i];
sum+=1;
}
i++;
}
return sum;
}
void range(int sum,int A[100], int *r1, int *r2)
{
int i,max,min;
max =0;
min = 32767;
*r1 = min;
*r2 = max;
for(i=0;i<sum;i++)
{
if (A[i]!=-1)
{
if (A[i]>max)
max = A[i];
if (A[i]<min)
min = A[i];
}
}
*r1 = max;
*r2 = min;
}
One of the problems is that you are not incrementing the value of i in function read_data.
The other problem is that the 4th printf
printf("%The number of elements is: %d\n",sum);
in the function main has a "%T" which is considered by the printf function to be a format specifier(like the one you use for the integer "%d"). If you really want to write % there you should use the format
printf("%%The number of elements is: %d\n",sum);
and it will print only one %.
If you would like to know more about the format specifiers accepted by printf http://www.cplusplus.com/reference/cstdio/printf/ .

can not pass all the test cases

problem:
Write a C program to implement Binary Search Algorithm.
Include a function
int BinarySearch (int, int, int *, int x) --- The 1st parameter is the lower limit of the list or array, the 2nd parameter is the upper limit of the list or array, the third parameter is a pointer to the array and the fourth parameter is the search element.
Please note that the index of the search element is returned by the function. If the search element is not present in the array, -1 is returned.
Assume that the maximum size of the array is 10 . Please note that if a is the array, then a[0] is in position 0, a[1] is in position 1 ...
I tried this ,but it's test cases passes says only 75%,and it can't find the element if n=1;Thanks in advance :)
#include<stdio.h>
int BinarySearch(int, int ,int *, int);
int main(){
int first=0, last;
int a[20],search,s=0,n,i;
//int j,temp=0;
printf("Enter the number of elements :\n");
scanf("%d",&n);
printf("Enter the elements :\n");
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
printf("Enter the element to be searched :\n");
scanf("%d",&search);
last=n-1;
s=BinarySearch(first, last, a, search);
if(s>0){
printf("The element %d is in position %d",search,s);
}
else{
printf("The element %d is not present in the array",search);
}
return 0;
}
int BinarySearch(int l, int h, int *a, int x)
{
int mid;
while(l<=h){
mid=(l+h)/2;
if (x==a[mid])
return mid;
else if(x<a[mid])
h=mid-1;
else if(x>a[mid])
l=mid+1;
}
return -1;
}

How to find the maximum value in an array of structures?

How to get the max value in a structure? I have tried to create a simple program but I'm having issues with the if statement or variable, since I cannot determine the winner or candidate number which has the highest score.
#include<stdio.h>
#include<conio.h>
struct Candidate{
float Score;
short Number;
}candidate1[5];
main(){
int i,n,highest;
for(i=0;i<5;i++){
printf("Candidate Number: ");
scanf("%i",&candidate1[i].Number);
printf("Score: ");
scanf("%i",&candidate1[i].Score);
highest=candidate1[i].Score;
for (n=0;n<5;n++)
if (candidate1[i].Score>highest);
}
printf("Highest Number: %i\n",highest);
system("pause");
}
fix like this
#include <stdio.h>
#include <stdlib.h>
struct Candidate {
float Score;
short Number;
}candidate1[5];
int main(void){
int i, n, highest = 0;
n = sizeof(candidate1)/sizeof(*candidate1);
for(i=0;i<n;++i){
printf("Candidate Number: ");
scanf("%hi", &candidate1[i].Number);
printf("Score: ");
scanf("%f",&candidate1[i].Score);
if(candidate1[highest].Score < candidate1[i].Score)
highest = i;
}
printf("Highest Number: %f\n", candidate1[highest].Score);
system("pause");
return 0;
}
,
The most common idiom for finding the max of type <T> (double, int, whatever) from an array of structs <S> goes as follows
<S> array[numElements]; //defined and allocated earlier. Has a score `<T> score`
<T> bestScore = array[0].score;
int bestIndex = 0;
int i;
for(i=1;i<numElements;i++) {
if(array[i].score>bestScore) {
bestIndex = i;
bestScore = array[i].score;
}
}
//do things with bestScore and array[bestIndex];
If you have a 2D array you can replace the single for-loop with a double for loop, and use an additional bestIndex variable for the second dimension.
If the array may contain 0 elements it is sometimes common to set bestScore to a minimum possible value and loop from 0 to numElements.

Resources