How do I write a function that have a input function (is objective to any function), array of input numbers and length of input array?
Function:
double accumulator(double (*function)(double, double), double array[], int length)
Main:
int main(){
double array[10];
for (int i=0; i<10; i++)
array[i] = i+1;
printf("Sum is: %g\n", accumulator(sum,array,10));
printf("Product is: %g\n", accumulator(product,array,10));
return 0;
}
For example sum should be 55 (1 + 2 + .... + 10) and product 362880 (1 * 2 * ... * 10).
I guess the function should by recursive but I still cant get the right results :/
I have got this non-recursive solution but it of course works only for sum...
double accumulator(double (*function)(double, double), double array[], int length)
{
int temp = 0;
for (int i = 0;i<length;i++)
{
temp = (*function)(temp, array[i]);
}
return temp;
}
on the top of course:
double sum(double x, double y){
return x+y;
}
double product(double x, double y){
return x*y;
}
What is wrong with:
double multiplicator(double (*function)(double, double), double array[], int length)
{
int temp = 1;
for (int i = 0;i<length;i++)
{
temp = (*function)(temp, array[i]);
}
return temp;
}
Either a different function or you need to supply the neutral element for the operation (0 for sum, 1 for product).
It doesn't work for multiplication because multiplying anything by 0 gives, well 0
you need to use first element as an initial value
double accumulator(double (*function)(double, double), double array[], int length)
{
int temp = array[0];
for (int i = 1; i < length;i++) // start from #1
{
temp = (*function)(temp, array[i]);
}
return temp;
}
Your solution is almost there if you set temp = array[0] and start your loop at i = 1 instead of i = 0.
Two thoughts:
You should use double temp rather than int temp.
You need to have a different starting value for addition versus multiplication. A sum should start at temp = 0, but a product should start at temp = 1. Otherwise the product will always be 0.
You could add add another initial value parameter:
double accumulator(double (*function)(double, double), double array[], int length, double initial)
Or you use the first array element as the starting value (but then you'll need to check for the special case where the array is empty):
double temp = array[0];
For what it's worth, your "accumulator" function is alternatively known as "reduce" in other functional programming contexts. That may help if you want to Google the term.
Related
Question: Given two arrays of integers A[] and B[] of size N and M, the task is to check if a pair of values (one value from each array) exists such that swapping the elements of the pair will make the sum of two arrays equal.
My approach:
find sum of both arrays.
Identify array with larger sum(denote with A[]).
Sort A.
For all values in B binary search (sum(A)-sum(B)/2 + B[i]) in A, if found return true.
Return false.
code:
int sum(int a[], int n){
int s=0;
for(int i=0; i<n; i++){
s+= a[i];
}
return s;
}
int findSwapValues(int A[], int n, int B[], int m)
{
// Your code goes here
int a = sum(A, n);
int b = sum(B,m);
int t;
int *temp;
if(a<b){
temp = A;
A = B;
B = temp;
t = n;
n = m;
m = t;
t = a;
a = b;
b = t;
}
sort(A, A+n);
for(int i=0; i<m; i++){
if(binary_search(A,A+n,(a-b)/2+B[i])){
return 1;
}
}
return -1;
}
Doubt: My algorithm is failing for some test cases(not TLE). As the test cases are very large, it's difficult to reason out the problem in the algorithm. I searched online and understood other approaches. My only curiosity is why its incorrect?
I think the error in your code is that you find B[i] + (a-b)/2.
The problem with this is that if (a-b) is an odd value, division by 2 will round it down to the nearest integer and you end up finding the wrong value.
What you can instead do is check if the difference is odd before even swapping the arrays, and if it is true, straight-away return -1 because if the difference is odd, no such pair can ever exist.
I hope I cleared your doubt :).
I have the following program.
#include <stdio.h>
double getAverage(int *arr[], int size) {
int i, sum = 0;
double avg;
for (i = 0; i < size; ++i)
{
printf("%d %d\n", i, arr[i]);
sum = sum + arr[i];
}
printf("%d\n", sum);
avg = (double)sum / size;
return avg;
}
int main ()
{
/* an int array with 5 elements */
int balance[5] = {1000, 2, 3, 17, 50};
double avg;
/* pass pointer to the array as an argument */
avg = getAverage( balance, 5 ) ;
/* output the returned value */
printf("Average value is: %f\n", avg );
return 0;
}
It's output is not correct. When I print the *arr[] values, the are not the same as the balance value. Do you know why and how I can fix this program?
0 1000
1 3
2 50
3 0
4 0
256992
Average value is: 51398.400000
Your function is declared like
double getAverage(int *arr[], int size)
That is, the first argument is supposed to be an array of pointers to int.
Then you call it as
getAverage( balance, 5 )
where balance is an array of int, which decays to a pointers to its first element (i.e. balance is equal to &balance[0]). This have the type int *.
The two types are mismatching, which the compiler should have warned you about.
The solution is to fix the function argument:
double getAverage(int *arr, int size)
The problem is here:
double getAverage(int *arr[], int size) {
You're passing a pointer to an array. That decays to a double pointer (a int**). You're using it like an int*, however. As a result, the pointer arithmetic under the hood is wrong. Change it to this:
double getAverage(int arr[], int size) {
It looks like on your setup, the pointers are twice as big as your ints, which is why it's always skipping a value (and ends up accessing invalid memory in the end).
If your compiler did not issue any warning for this code, try to see if you can set it to be more strict with warnings.
int main()
{
double dUnitPriceM[]={19.99, 50.50, 2.10};
long lOrderQuantityM[] = {10, 2, 4};
int iItemCount = 3;
double dTotalCost;
dTotalCost = calculateTotalCost(dUnitPriceM, lOrderQuantityM, iItemCount);
printf("Total cost is %10.2lf\n", dTotalCost);
}
// code for calculateTotalCost function ??
double calculateTotalCost(double dUnitPriceM[], long lQuantityM[],
int iItemCount)
{
}
I am a beginner for coding C language and I am having trouble understanding how to use Arrays. I came up with the logic of creating a pseudocode but I cant code it.
All I know is that I have to start from the value of i =1; as i <= Item count, i++.
then assign i the result of the UnitPriceM[0] * QuantityM[0], increment them to the next array until it has reached its last value. Then sum the total of all the i's for example if i1= 100 + i2 = 120 + i3 =45 return them as the total cost.
#include <stdio.h>
double calculateTotalCost(double unitPrice[], long quantity[],int itemCount){
int i;
double totalCost=0.0;
for(i=0;i<itemCount;i++){
totalCost +=unitPrice[i] * quantity[i];
}
return totalCost;
}
void main() {
int i;
double dUnitPriceM[]={19.99, 50.50, 2.10};
long lOrderQuantityM[] = {10, 2, 4};
int iItemCount = 3;
double totalCost =0.0;
totalCost= calculateTotalCost(dUnitPriceM, lOrderQuantityM, iItemCount);
printf("Total cost is %f ", totalCost);
}
Here it is the basic logic of looping through all and doing the operation required.
double calculateTotalCost(double dUnitPriceM[], long lQuantityM[],
int iItemCount)
{
double sum=0;
for(int i=0;i<iItemCount;i++)
{
sum=sum+dUnitPriceM[i]*lQuantityM[i];
}
return sum;
}
I am extremely new to C and managed to compile this program, but the exe stops working upon running. I'm really not sure what's wrong.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define TINY 1.0e-20 // A small number.
void ludcmp(float a[3][3], int n, int *indx, float *d);
void lubksb(float a[3][3], int n, int *indx, float b[]) ;
int main(){
int i,n,*indx;
float *b,d;
float a[3][3] = {
{ 1.0, 2.0, 5.0},
{-1.0, 2.0, 3.0},
{ 6.0, 0.0, 1.0}
};
ludcmp(a,n,indx,&d);
lubksb(a,n,indx,b);
for(i = 1; i = 3; i++) {
printf("%.2f",b[i]);
}
getchar();
return 0;
}
For those who were asking, the 2 functions ludcmp and lubksg are below. I got them from the numerical recipes textbook, but edited some lines to remove exclusive routines which I do not have. Specifically, they are the lines with malloc, printf, and free.
The original code came with all the loops starting with 1, which is why I also started my loop with 1. I have since changed all the loops to start from 0 instead, hopefully without introducing any new errors.
You can see the original code here:
https://github.com/saulwiggin/Numerical-Recipies-in-C/tree/master/Chapter2.Solution-of-Linear-Equations
Here is ludcmp:
void ludcmp(float a[3][3], int n, int *indx, float *d)
{
int i, imax, j, k;
float big, dum, sum, temp;
float *vv; // vv stores the implicit scaling of each row.
vv = (float *) malloc(n * sizeof(float));
*d=1.0;
for (i=0;i<n;i++) {
big=0.0;
for (j=0;j<n;j++)
if ((temp=fabs(a[i][j])) > big) big=temp;
if (big == 0.0)
{
printf("Singular matrix in routine ludcmp");
//free(vv);
}
// No nonzero largest element.
vv[i] = 1.0 / big; // Save the scaling.
}
// This is the loop over columns of Crout's method.
for (j=0;j<n;j++) {
for (i=0;i<j;i++) {
sum=a[i][j];
for (k=0;k<i;k++) sum -= a[i][k]*a[k][j];
a[i][j]=sum;
}
// Initialize for the search for largest pivot element.
big=0.0;
for (i=j;i<=n;i++) {
sum=a[i][j];
for (k=0;k<j;k++)
sum -= a[i][k]*a[k][j];
a[i][j]=sum;
if ( (dum=vv[i]*fabs(sum)) >= big) {
big=dum;
imax=i;
}
}
if (j != imax) {
for (k=0;k<n;k++) {
dum=a[imax][k];
a[imax][k]=a[j][k];
a[j][k]=dum;
}
*d = -(*d);
vv[imax]=vv[j];
}
indx[j]=imax;
if (a[j][j] == 0.0) a[j][j]=TINY;
if (j != n) {
dum=1.0/(a[j][j]);
for (i=j+1;i<n;i++) a[i][j] *= dum;
}
} // Go back for the next column in the reduction.
free(vv);
}
And lubksb:
void lubksb(float a[3][3],int n,int *indx,float b[])
{
int i,ii=0,ip,j;
float sum;
for (i=1;i<=n;i++) {
ip=indx[i];
sum=b[ip];
b[ip]=b[i];
if (ii)
for (j=ii;j<=i-1;j++) sum -= a[i][j]*b[j];
else if (sum) ii=i;
b[i]=sum;
}
for (i=n;i>=1;i--) {
sum=b[i];
for (j=i+1;j<=n;j++) sum -= a[i][j]*b[j];
b[i]=sum/a[i][i];
}
}
This is a Two Dimensional Array and you are looping as it was just one. You should do something like:
for (int i = 0; i < 3; ++i) {
for(int j = 0; j < 3; ++j) {
printf("%d %d: ", i+1, j+1);
}
}
Is bad practice to define the size of the array explicit. Try to use a constant.
And as said in the comments by #Marged:
In C arrays starts in 0
b is never assigned to anything valid when it's declared:
float *b,d;
At best, it's NULL or pointing to an invalid memory address:
I don't know what the lubksb function does:
lubksb(a,n,indx,b);
But b is clearly an invalid parameter since you never assign to it before calling this function.
And with this statement:
for(i = 1; i = 3; i++) {
printf("%.2f",b[i]);
}
As others have pointed out, array indices start at zero. But there's no evidence that b has a length of three anyway.
I am new to C and have a question about making a simple function in which I hand in a given array and also an integer that tells the number of numbers in that array. I wrote this code but I am unsure if it is correct. What I was trying to do was to make it so that I could find the product of all the numbers in the array.
#include <stdio.h>
#include <math.h>
double my_product (int n, double x[]);
int main (void)
{
my_product(n, x);
return 0;
}
double my_product (int n, double x[])
{
int i;
product=0;
for(i=0; i<n; i++)
{
product=x[i]*x[i+1]
}
return product;
}
I will comment your code, pointing out your mistakes:
double my_product (int n, double x[])
{
int i;
product=0;
/* The variable "product" needs to have a type.
In your case, since your values have type "double",
and a "double" return is expected,
of course you need to declare:
double product;
On the other hand,
it has not sense to initialize a product to 0,
since multiplication by 0 "kills" every value,
giving you a value 0, not matter what you do.
So, initialize in this way:
double product = 1.0;
*/
for(i=0; i<n; i++)
{
/* A semicolon is missing in the next line: */
product=x[i]*x[i+1]
/* In every step of the loop,
the variable "product" will hold the value
given by the multiplication of two consecutive values
in the array.
Thus, you lose every previous factor.
Also, when i == n you are in trouble,
because x[i] == x[n] is beyond the limits of the array,
which may cause access violation to memory.
You need a cumulative product.
Starting by the initialized value 1.0,
you have to multiply the previous value of "product"
with the present value of the array: x[i]
product = product * x[i];
Thus, in the step i, it can be proved that
the variable "product" contains the cumulative product
of the factors x[0], x[1], ... up to x[i].
A more compact notation in C can be provided by the *= operator:
product *= x[i];
*/
}
return product;
}
In the function main():
int main (void) {
my_product(n, x);
/* The function "my_product()" has been called with
undeclared parameters "n" and "x".
First, you have to declare and define the value of "n",
as much as the array "x", having type double:
double x[] = {3.0, 1.41, -2.3, 9.4, };
int n = sizeof(x)/sizeof(double);
The first line would declare an array "x" having type "double",
and initialized to hold 4 values, as it's seen there.
The second line would declare an "int" variable "n"
holding the number of elements in the array,
which can be computed as the size of x (measured in bytes)
divided by the size of the type "double"
(of course, in this example we have n == 4).
Finally, you need to do something with the result returned by
the function "my_product()".
If not, the returned value will be completely lost.
For example, to hold it in a variable, or to show it on screen.
double ans;
ans = my_product(n, x);
*/
return 0;
}
The code will look like this:
#include <stdio.h>
#include <math.h>
double my_product (int n, double x[]);
int main (void)
{
double x[] = {3.0, 1.41, -2.3, 9.4, };
int n = sizeof(x)/sizeof(double);
double ans;
ans = my_product(n, x);
printf("Product is: %f\n", ans);
return 0;
}
double my_product (int n, double x[])
{
product=1.0;
int i;
for(int i=0; i<n; i++)
{
product *= x[i];
}
return product;
}
In your function my_product you overwrite the value of product in the loop
for(i=0; i<n; i++)
{
product=x[i]*x[i+1]
}
So suppose your array x = {2, 3, 4}, then first product gets the value of 2*3, but then you overwrite it with the value of 3*4. What you probably want is to use a variable in which you accumulate the results of the multiplications (e.g. total = total * number).
Also, watch out with your indexing. In your current code i+1 can be larger than the number of elements in x, so you run out of the array.