How would you implement a function with the same behavior as List.scan in F#?
Here is the description:
Applies a function to each element of the collection, threading an
accumulator argument through the computation. This function takes the
second argument, and applies the function to it and the first element
of the list. Then, it passes this result into the function along with
the second element, and so on. Finally, it returns the list of
intermediate results and the final result. (link)
Of course I have attempted myself and here is my pseudocode (I do not expect you to provide working c-code btw): For the call scan(myop, ne, x), I have the pseudocode
int n = length(x);
char *b = (char*)malloc(n); //Allocate n bytes
b[0] = ne;
int i = 0;
while (i < n) {
bool tmp = myop(b[i-1], x[i]);
bool b[i] = tmp;
i = i+1;
}
bool list y = b;
but this fails for i > 0 since then b[i] is not initialized. How would you implement this?
but this fails for i > 0 since then b[i] is not initialized
In your pseudo code:
bool tmp = myop(b[i-1], x[i]);
It will be failed when i = 0 (it means at the first time you enter the while loop), because you try to access the index -1 (i = 0, so b[i-1] becomes b[-1]) of b, it is undefined behavior.
You have to begin the while loop at i = 1 at least. So, before the loop:
b[0] = ne;
int i = 0;
Can change to:
b[0] = ne;
// do something with b[0] if you want.
int i = 1;
In your code, you refer to the previous element even for i == 0, which is incorrect. You could special case the first element by storing b[0] = myop(ne, x[0]) and start the loop at i = 1, but this solution would not work for an empty source list (n == 0). Furthermore, length(x) cannot be computed from a pointer, only from an actual array as sizeof(x) / sizeof(*x). It is best to pass the size as a separate argument.
Here is a C function that performs the semantics of List.scan for int arguments, taking a pointer to the function, an initial value, an array of int values, the length of this array and a pointer to the destination array, which can be the same as the source array:
int array_scan(int (*func)(int, int), int v1, const int *src, size_t count, int *dest) {
for (size_t i = 0; i < count; i++) {
int v2 = src[i];
dest[i] = v1;
v1 = func(v1, v2);
}
return v0;
}
In C there is no way to define lambda expressions inline, so you must define the function separately with a name and pass it explicitly to array_scan.
Related
I am learning C, and I came across this problem I can't figure it out. Write a function that computes the element of an integer array a plus 6 modulus 10 and store the result in array b. For example, if 5 is the second element of array a, then the second element of array b should be (5+6)%10, which is 1. The function has the following prototype, n is the length of the arrays, a and b are the integer arrays.
I did:
void arithmetic (int *a, int n, int *b)
{
int *arr1; arr1=a; int *arr2; arr2=b;
int i;
for(i = 0; i < n; i++) {
*arr1 = *(((a + i) + 6) % 10);
*arr2 = *arr1;
}
}//don't know if the function is correct.
A couple things:
No need to update the actual content of the first array (which fixes the error pointed out about your code always storing the result in the first element of a)
Use some parens to make sure you get the right order of operations.
void newArr(int *a, int n, int *b) {
int *arr1; arr1 = a; int *arr2; arr2 = b;
for (int i = 0; i < n; i++) {
*(arr2 + i) = (*(arr1 + i) + 6) % 10;
}
}
Think about your title "...using Pointer arithemtic". You need to add the loop counter to the array pointer for both arr1 and arr2 so that it steps through each element of each array: *(arr2 + i) and *(arr1 + i).
This is also a good place to reinforce the fact that the pointers are passed by value and that the function receives copy of each pointer which it is free to iterate with to affect the copy without effecting the pointers in the caller. So it would also be perfectly valid to do:
void arithmetic (int *a, int *b, size_t n)
{
if (!a || !b)
return;
for(size_t i = 0; i < n; i++, a++, b++)
*b = (*a + 6) % 10;
}
(good job Pablo with the use of size_t for the length (or number of elements) parameter)
No, your function is not correct.
*arr1 = *((a+i)+6)%10);
You are only writing the values in the first element of the array.
arr1 points to a which already has the values. You want to do the
calculation with a value stored in a and then save it to b, so don't modify
a.
*((a+i+6)%10) is completely wrong. a+i+6 is the same as &a[i+6]. The %10
applies to the value &a[i+6] (which is the address of the i+6th element), and returns a value between 0 and 9 (let's call
it x). When do *(x) you are interpreting the x as a pointer and it
dereferences (=access the value through the pointer) it, but this is not a valid
address at all. You will also eventually access a out of bounds.
*arr2 = *arr1; here you also only storing the values in the first element of arr2.
You function has no name.
int *arr1; arr1=a; this is unnecessary, you can access a directly, no
need to create a copy of the pointer.
The +6 % 10 rule applies to the values stored in the array, not the indices.
The correct function should look like this:
void compute(int *a, int *b, size_t len)
{
if(a == NULL || b == NULL)
return;
for(size_t i = 0; i < len; ++i)
b[i] = (a[i] + 6) % 10;
}
And if your assignment says you should do it with pointer arithmetic instead of
using array indexing:
void compute(int *a, int *b, size_t len)
{
if(a == NULL || b == NULL)
return;
for(size_t i = 0; i < len; ++i)
*(b+i) = (*(a + i) + 6) % 10;
}
Just started learning C programming and decided to take a class in algorithmic Toolbox on Coursera. One of the challenges is writing a code using fractional knapsack, maximizing the value of loot and a pseudo code was given to help in coding the solution. Below are the pseudo code and the code I wrote for the pseudo code.
#include<stdio.h>
int min(int a, int b)
{
if (a < b)
return a;
else
return b;
}
int knapsack(int value[], int weight[])
{
int capacity = 100;
int val = 0;
int array[] = { 0 };
for (int i = 1; i < capacity; i++)
{
if (capacity == 0)
{
return val;
}
for (int i = 1; i < capacity; i++)
{
if (weight[i] > 0 && (value[i] / weight[i]))
{
int a = min(weight[i], capacity);
val = val + a * (value[i] / weight[i]);
weight[i] = weight[i] - a;
array[i] = array[i] + a;
capacity = capacity - a;
}
}
}
return val;
}
int main()
{
int value[100];
int weight[100];
scanf("%d", &value[100]);
scanf("%d", &weight[100]);
printf("%d", knapsack(value[100], weight[100]));
return 0;
}
pseudo code
Knapsack(W, w1,v1,......wn,vn)
A <-- [0,0,], V <-- 0;
repeat n times:
if W = 0:
return (V,A)
select i with Wi > 0 and max vi/wi
a <-- min(wi, W)
V <-- V + a(vi/wi)
wi <-- wi - a, A[i] <-- A[i] + a, W <-- W - a
return (V, A)
I am getting errors when I compile such as "passing argument 1 of 'knapsack' makes pointer from integer without a cast [-Wint-conversion]"
printf("%d", knapsack(value[100],weight[100]));
"expected int * but argument is of type 'int'"
int knapsack(int value[], int weight[])
I also want to know if it is a good practice to declare int value[], int weight[] in the function int knapsack argument and also more explanation in using arrays and pointers in situations like this.
int knapsack(int value[], int weight[])
The above statement gives the compiler the information about HOW the function should be called (type of arguments) and WHAT the function will return.
It says the function knapsack will return an integer value (the 1st int).
Its name is knapsack (case-sensitive).
It expects two arguments: an integer array (named value) and an integer array (named weight).
Points 1, 2 and 3 together make up the signature of a function.
To call the function you have to pass 2 integer arrays as its arguments.
The mistake : value[100] corresponds to an INTEGER ENTRY in the array and not the array itself.
To pass the array you should pass the array name as its argument, which your function expects.
Call the function like this: knapsack(value, weight)
value corresponds the array value and weight corresponds to the array weight
Also, passing value[100] corresponds to some garbage value that is not within the array bounds as you can only access elements ranging from value[0] to value[99] (0-based indexing).
I did some googling and I'm pretty sure this is impossible in C, as constants are created during the compiling..
Anyways, I would still like to ask it it's possible. I would like to generate arrays in a loop with loop defined length like this:
#include <stdio.h>
#define ROWCOL_MULTIPLIER 50
main() {
for (int loop = 0; loop < 11; loop++) {
const int val = loop * ROWCOL_MULTIPLIER;
double b[val] = malloc(sizeof(double)* val * val);
// do foo things
free(b);
}
return 0;
}
This is what I needed to accomplish http://ideone.com/fork/TyGZVV
#include <stdio.h>
#include <stdlib.h>
#define ROWCOL_MULTIPLIER 1
main() {
size_t loop, i, j = 0;
for (loop = 0; loop < 5; loop++) {
const double val = (loop + 1) * ROWCOL_MULTIPLIER;
double *column_sum = malloc(val * sizeof *column_sum);
double *p = malloc(val * val * sizeof *p);
printf("\n%i\n", loop + 1);
for (i = 0; i < val; ++i){
column_sum[i] = *(double*)&i;
for (j = 0; j < val; ++j){
int index = i * (int)val + j;
p[index] = *(double*)&j;
double offsetI = column_sum[i];
double offsetJ = p[index]++;
printf("%d->", offsetI);
printf("%d,", offsetJ);
}
printf("\n");
}
free(p);
free(column_sum);
}
}
In C89, double b[val] is illegal, because a const variable does not count as a compile-time constant.
In any version of C, double b[val] = malloc... is illegal because an array can only be initialized by values matching its element type. An array of doubles can contain things like 3.1, 7.2 - not malloc.
In C99 you can write:
double b[val];
which is an array of val doubles. If you want val * val doubles you can write double b[val * val];, or double b[val][val]; or anything else along those lines. This array uses automatic storage (sometimes called stack) and is freed when the code block including this definition ends.
In any version of C you can use dynamic storage. In that case you must use a pointer to refer to the storage, e.g.:
double *p = malloc( val * sizeof *p );
double *p = malloc( val * val * sizeof *p );
In C99 you can combine malloc with variably-modified types, this will let you use 2-D array access syntax:
double (*p)[val] = malloc(val * sizeof *p);
for (size_t i = 0; i < val; ++i)
for (size_t j = 0; j < val; ++j)
p[i][j] = 0.0;
There is a major difference between a compile-time constant and a const variable: The compile-time constant can (duh!) be computed at compile time. For the C compiler, this means that the amount of space that must be reserved for an array of size X can be computed if X is a compile-time constant. If X is simply const then amount of space to reserve for the array cannot be known at compile time.
Since the C compiler essentially creates a struct for each automatic storage frame, and since the size of all the elements of a struct must be known at compile time, if you want to declare an array that is allocated in automatic storage it must have a size that is a compile-time constant. Similarly, if you want to declare an array that is allocated as a part of a struct or class, its size must be known at compile time.
I would like to store values read from a for-loop to an array
char A[];
int x;
int y=5;
for( int i=0; int i =1000; i++) {
x = x+y;
// then store/append x as elements of the char array, A.... what is the syntax?
}
By looking at your code I am assuming that you are trying to build a static array, so I will demonstrate that (so you don't have to focus on concepts like malloc for the time being). There is however, several problems with your code that I will go over now.
First off your array declaration:
char A[];
to me it looks like your for loop is filling an array of integers, so this array should be declared as an integer, furthermore you are not setting the size of the array, since your code has i increment until it is 1000 you should just declare an integer array with 1000 elements:
int A[1000];
Second your for loop:
for(int i = 0, int i = 1000; i++)
you're better off just declaring i with the rest of your variables, although you can declare it in a for loop I personally wouldn't suggest doing it. Also you declare i twice in this loop. Finally your condition to continue the loop (i = 1000) will abort the loop immediatly since i will never be equal to 1000 since you set it to 0. Remember a for loop only loops while the middle statement is true. So with that in mind you should now have:
int A[1000], i, x, y = 5;
for(i = 0; i < 1000; i++)
And now we can use the = statement and the value of i to set each array element for A:
int A[1000], i, x, y = 5;
for(i = 0; i < 1000; i++)
{
x += y;
A[i] = x;
}
it's that simple!
There are multiple issues with your code
char A[1000]; // Need to specify a compile time constant for the array size
int x=0;
int y=5;
for( int i=0; i < 1000; i++) { // Condition was wrong
x = x+y;
// then store/append x as elements of the char array, A.... what is the syntax?
A[i] = x; // Add the value
}
Also, the char datatype won't be able to hold values over a certain size, and will cause overflow making the values wrap around. You might want to declare A as int A[1000] instead.
Arrays need to be of a constant size, or you will need to allocate them using malloc
The second part of the loop cannot redeclare i again. It also will loop forever if you have an assignment statement in it like you do. I assume you want to loop up to 1000 instead
The actual question, to assign into an array use the [] operator.
x was not initialized to anything, making it contain a garbage value. You need to assign values to variables upon declaring them. C does not do this for you automatically.
If you want to add an element in C, you have several methods.
Static array
A static array is declared with a number of elements you're unable to edit. So it's perfect if you know exactly the number of elements you'll have. #Dervall did explain that well.
Dynamic array
A dynamic array is declared with malloc function. And the size can be changed. It's difficult and hard to maintain though. But :
int *A = NULL;
int *tmp; // to free ex allocated arrays
int i;
int j;
int x = 0;
int y = 5;
for (i = 0 ; i < 1000 ; i++) {
// saving temporarly the ex array
tmp = A;
// we allocate a new array
if ((A = malloc(sizeof(int) * (i + 1))) == NULL) {
return EXIT_FAILURE;
}
// we fill the new array allocated with ex values which are in tmp
for (j = 0; j < i; j++) {
A[j] = tmp[j];
}
// if it's not the first time, we free the ex array
if (tmp != NULL)
free(tmp);
x = x + y;
A[i] = x;
}
Better to split it into a function of course :)
You can use the realloc function as well ! Which is made for that, but I find it interesting to develop like this
There's a lot of stuff wrong with your snippet. Here's a compilable example
char *A = malloc(sizeof(*A) * NUM_ELEMENTS); // you shouldn't declare on the stack
int x = 0; // initialize
int y=5;
for( int i = 0; i < NUM_ELEMENTS; i++) { // proper for loop syntax
x = x+y;
A[i]=x; // assign element of array
}
And a better version:
char *A = malloc(sizeof(*A) * NUM_ELEMENTS);
for (int i = 0; i < NUM_ELEMENTS; ++i)
A[i] = 5 * i;
I'm trying to sort a 2d array of pointers using qsort. The only issue I have right now is originally I was using statically declared arrays now switching over to pointers. I'm almost tempted to switch to structs but being stubborn that I can't get this to work.
So far I malloc the 2d array of pointers[array2d[m][3] was the intended size]:
int **array2d;
array2d = (int**)malloc((m)*sizeof(int*));
for(i=0; i<=m; i++)
array2d = [i]=(int*)malloc(3*sizeof(int));
qsort(array2d, m, 3*sizeof(int**),comp);
My compare is:
int comp(const void* left, const void*right)
{
const int *a = *(const int**)left;
const int *b = *(const int**)right;
return a-b;
}
Although I'm not sure how to structure the compare to work with 2d pointers.
From the code snippet you provided I am assuming you were trying to sort each row of the matrix separately. The first thing I noticed is that there is a typo in the memory allocation of columns (2nd index) of the matrix.
Correct memory allocation of a numRow x numColumns matrix would be as follows:
/* loop counter */
int i;
/* dynamic array sizes */
const int numRow = 5;
const int numColumns = 25;
/* allocate the row pointers */
int **dynamic2d = (int **)malloc(numRow * sizeof(int *));
/* for each row pointer */
for(i = 0; i < numRow; i++)
{
/* allocate columns */
dynamic2d[i] = (int *)malloc(numColumns * sizeof(int));
}
Next you won't be able to simply call the qsort(..) method only once. That method expects a "flat" or one-dimensional array. You will need to call the qsort(...) method separately for each row of the matrix. This is demonstrated below:
/* sort array */
for(i = 0; i < numRow; i++)
qsort(dynamic2d[i], numElements, sizeof(int *), comp);
Lastly, you made a mistake with your comparator method. This method has strict rules that need to be followed in order to work correctly. Current specifications say, "The application shall ensure that the function returns an integer less than, equal to, or greater than 0, if the first argument is considered respectively less than, equal to, or greater than the second. If two members compare as equal, their order in the sorted array is unspecified."
This is a simple fix. Simply write the logic to produce those results as seen below:
int comp(const void* firstArg, const void* secondArg)
{
/* get the values of the arguments */
int first = *(int *)firstArg;
int second = *(int *)secondArg;
/* return the value as expected by the qsort() method */
if(first < second)
{
return 1;
}
else if(second < first)
{
return -1;
}
return 0;
}
Last thing to note, this will sort greatest to least. Do not switch the logic around in the comparator if you want least to greatest. The sort will not return accurate results. The correct way to do this is by reading the array from back to front as seen below: You can swap the arguments in the comparator to change the sorting order or read the results from back to front.
int comp(const void* firstArg, const void* secondArg)
{
/* get the values of the arguments */
int first = *(int *)secondArg;
int second = *(int *)firstArg;
...
}
or
/* print greatest to smallest */
for(i = 0; i < numRow; i++)
{
/* start at front and work to back */
for(j = 0; j < numColumns; j++)
printf("%d ", dynamic2d[i][j]);
printf("\n");
}
/* print smallest to greatest */
for(i = 0; i < numRow; i++)
{
/* start at back and work to front */
for(j = numColumns- 1; j >= 0; j--)
printf("%d ", dynamic2d[i][j]);
printf("\n");
}
Hopefully this helps! If you need to sort the entire matrix as a whole... that is a different beast all together.