Related
I have a recursive function that I wrote in C that looks like this:
void findSolutions(int** B, int n, int i) {
if (i > n) {
printBoard(B, n);
} else {
for (int x = 1; x <= n; x++) {
if (B[i][x] == 0) {
placeQueen(B, n, i, x);
findSolutions(B, n, i + 1);
removeQueen(B, n, i, x);
}
}
}
}
The initial call is (size is an integer given by user and B is a 2D array):
findSolutions(B, size, 1);
I tried to convert it into a iteration function but there is another function called removeQueen after findSolutions. I got stuck on where to put this function call. How to solve this problem? Stack is also fine but I'm also having trouble doing that.
I'm going to assume that placeQueen(B, n, i, x) makes a change to B and that removeQueen(B, n, i, x) undoes that change.
This answer shows how to approach the problem generically. It doesn't modify the algorithm like Aconcagua has.
Let's start by defining a state structure.
typedef struct {
int **B;
int n;
int i;
} State;
The original code is equivalent to the following:
void _findSolutions(State *state) {
if (state->i >= state->n) {
printBoard(state->B, state->n);
} else {
for (int x = 1; x <= state->n; ++x) {
if (state->B[state->i][x] == 0) {
State *state2 = State_clone(state); // Deep clone.
placeQueen(state2);
++state2->i;
findSolutions(state2);
}
}
}
State_free(state); // Frees the board too.
}
void findSolutions(int** B, int n, int i) {
State *state = State_new(B, n, i); // Deep clones B.
_findSolutions(state);
}
Now, we're in position to eliminate the recursion.
void _findSolutions(State *state) {
StateStack *S = StateStack_new();
do {
if (state->i >= state->n) {
printBoard(state->B, state->n);
} else {
for (int x = state->n; x>=1; --x) { // Reversed the loop to maintain order.
if (state->B[state->i][x] == 0) {
State *state2 = State_clone(state); // Deep clone.
placeQueen(state2);
++state2->i;
StateStack_push(S, state2);
}
}
}
State_free(state); // Frees the board too.
} while (StateStack_pop(&state));
StateStack_free(S);
}
void findSolutions(int** B, int n, int i) {
State *state = State_new(B, n, i); // Deep clones B.
_findSolutions(state);
}
We can eliminate the helper we no longer need.
void findSolutions(int** B, int n, int i) {
StateStack *S = StateStack_new();
State *state = State_new(B, n, i); // Deep clones B.
do {
if (state->i >= state->n) {
printBoard(state->B, state->n);
} else {
for (int x = state->n; x>=1; --x) { // Reversed the loop to maintain order.
if (state->B[state->i][x] == 0) {
State *state2 = State_clone(state); // Deep clone.
placeQueen(state2);
++state2->i;
StateStack_push(S, state2);
}
}
}
State_free(state); // Frees the board too.
} while (StateStack_pop(S, &state));
StateStack_free(S);
}
Functions you need to implement:
StateStack *StateStack_new(void)
void StateStack_free(StateStack *S)
void StateStack_push(StateStack *S, State *state)
int StateStack_pop(StateStack *S, State **p)
State *State_new(int **B, int n, int i) (Note: Clones B)
State *State_clone(const State *state) (Note: Clones state->B)
void State_free(State *state) (Note: Frees state->B)
Structures you need to implement:
StateStack
Tip:
It would be best if you replaced
int **B = malloc((n+1)*sizeof(int*));
for (int i=1; i<=n; ++i)
B[i] = calloc(n+1, sizeof(int));
...
for (int x = 1; x <= n; ++x)
...
B[i][x]
with
char *B = calloc(n*n, 1);
...
for (int x = 0; x < n; ++x)
...
B[(i-1)*n+(x-1)]
What you get by the recursive call is that you get stored the location of the queen in current row before you advance to next row. You will have to re-produce this in the non-recursive version of your function.
You might use another array storing these positions:
unsigned int* positions = calloc(n + 1, sizeof(unsigned int));
// need to initialise all positions to 1 yet:
for(unsigned int i = 1; i <= n; ++i)
{
positions[i] = 1;
}
I reserved a dummy element so that we can use the same indices...
You can now count up last position from 1 to n, and when reaching n there, you increment next position, restarting with current from 1 – just the same way as you increment numbers in decimal, hexadecimal or octal system: 1999 + 1 = 2000 (zero based in this case...).
for(;;)
{
for(unsigned int i = 1; i <= n; ++i)
{
placeQueen(B, n, i, positions[i]);
}
printBoard(B, n);
for(unsigned int i = 1; i <= n; ++i)
{
removeQueen(B, n, i, positions[i]);
}
for(unsigned int i = 1; i <= n; ++i)
{
if(++positions[i] <= n)
// break incrementing if we are in between the numbers:
// 1424 will get 1431 (with last position updated already before)
goto CONTINUE;
positions[i] = 1;
}
// we completed the entire positions list, i. e. we reset very
// last position to 1 again (comparable to an overflow: 4444 got 1111)
// so we are done -> exit main loop:
break;
CONTINUE: (void)0;
}
It's untested code, so you might find a bug in, but it should clearly illustrate the idea. It's the naive aproach, always placing the queens and removing them again.
You can do it a bit cleverer, though: place all queens at positions 1 initially and only move the queens if you really need:
for(unsigned int i = 1; i <= n; ++i)
{
positions[i] = 1;
placeQueen(B, n, i, 1);
}
for(;;)
{
printBoard(B, n);
for(unsigned int i = 1; i <= n; ++i)
{
removeQueen(B, n, i, positions[i]);
++positions[i]
if(++positions[i] <= n)
{
placeQueen(B, n, i, positions[i]);
goto CONTINUE;
}
placeQueen(B, n, i, 1);
positions[i] = 1;
}
break;
CONTINUE: (void)0;
}
// cleaning up the board again:
for(unsigned int i = 1; i <= n; ++i)
{
removeQueen(B, n, i, 1);
}
Again, untested...
You might discover that now the queens move within first row first, different to your recursive approach before. If that disturbs you, you can count down from n to 1 while incrementing the positions and you get original order back...
At the very end (after exiting the loop), don't forget to free the array again to avoid memory leak:
free(positions);
If n doesn't get too large (eight for a typical chess board?), you might use a VLA to prevent that problem.
Edit:
Above solutions will print any possible combinations to place eight queens on a chess board. For an 8x8 board, you get 88 possible combinations, which are more than 16 millions of combinations. You pretty sure will want to filter out some of these combinations, as you did in your original solution as well (if(B[i][x] == 0)), e. g.:
unsigned char* checks = malloc(n + 1);
for(;;)
{
memset(checks, 0, (n + 1));
for(unsigned int i = 1; i <= n; ++i)
{
if(checks[positions[i]] != 0)
goto SKIP;
checks[positions[i]] = 1;
}
// place queens and print board
SKIP:
// increment positions
}
(Trivial approach! Including the filter in the more elaborate approach will get more tricky!)
This will even be a bit more strict than your test, which would have allowed
_ Q _
Q _ _
_ Q _
on a 3x3 board, as you only compare against previous column, whereas my filter wouldn't (leaving a bit more than 40 000 boards to be printed for an 8x8 board).
Edit 2: The diagonals
To filter out those boards where the queens attack each other on the diagonals you'll need additional checks. For these, you'll have to find out what the common criterion is for the fields on the same diagonal. At first, we have to distinguish two types of diagonals, those starting at B[1][1], B[1][2], ... as well as B[2][1], B[3][1], ... – all these run from top left to bottom right direction. On the main diagonal, you'll discover that the difference between row and column index does not differ, on next neighbouring diagonals the indices differ by 1 and -1 respectively, and so on. So we'll have differences in the range [-(n-1); n-1].
If we make the checks array twice as large and shift all differences by n, can re-use do exactly the same checks as we did already for the columns:
unsigned char* checks = (unsigned char*)malloc(2*n + 1);
and after we checked the columns:
memset(checks, 0, (2 * n + 1));
for(unsigned int i = 1; i <= n; ++i)
{
if(checks[n + i - positions[i]] != 0)
goto SKIP;
checks[n + i - positions[i]] = 1;
}
Side note: Even if the array is larger, you still can just memset(checks, 0, n + 1); for the columns as we don't use the additional entries...
Now next we are interested in are the diagonals going from bottom left to top right. Similarly to the other direction, you'll discover that the difference between n - i and positions[i] remains constant for fields on the same diagonal. Again we shift by n and end up in:
memset(checks, 0, (2 * n + 1));
for(unsigned int i = 1; i <= n; ++i)
{
if(checks[2 * n - i - positions[i]] != 0)
goto SKIP;
checks[2 * n - i - positions[i]] = 1;
}
Et voilà, only boards on which queens cannot attack each other.
You might discover that some boards are symmetries (rotational or reflection) of others. Filtering these, though, is much more complicated...
I have broken my head trying to solve this question on an exam. I'm stil shocked by it.
Can anybody help me write a function:
void get2(int a[], int n, *i1, *i2)
that receives the massive a[] of integers and his length n and saves to pointers i1 and i2 the indexes of the two biggest numbers in the massive (i1 - the biggest, i2 - the second biggest).
The solution must be recursive and can not contain loops. It has be done by the complextiy of O(n). The numbers in the massive are all diffrent. We cant use any helper functions.
There aren't any additional conditions. I tried some solutions, but they werent good enough.
I dont know how to save the indexes without losing there values when I recurse.
There was additional hint, that I should pay attention to how I use the *i1, *i2 to pass information between recursive steps, but i tried to use it some how and it didn't work for me anything I tried. Help somebody ?
There is only one trick to play on this exercise: Recognize when we are in the outermost recursive call and when we are not, or simpler terms when the current call of get2 is the first one and when it is not.
Using the pointers and the n parameter to do some basic Divide et Impera strategy is straightforward and require no further explanation.
We need to tell the first and subsequent calls because in the first, and only there, call we need to initialize the pointers.
We cannot rely on i1 or i2 values as they are uninitialized.
Only n has enough structure to carry some information: When we are called from the extern, i.e. not by recurring, then n >= 0.
We can then perform the one-time initialization and then negate n. This way if n<=0 we know that we are in the recursive calls.
However we still have a problem: if n >= 0 then it's opposite is n <= 0. The two condition overlaps for n == 0.
This will make the initialization happen two time and further worst the second one at the end of the recursion stack thereby voiding the state calculated.
In order to avoid them, the n is not simply negated but negated and decremented by 1, so the 5 becomes -6.
We can then recover the usable value of n by again negating and decrementing by 1. In the code below this is done and stored in m.
The else part is straightforward as pointed above. We only additionally check that the second maximal element is not equal to the maximal element in the second if.
If one index is -1 it means that it is not pointing to any element and can be assigned unconditionally.
When the function return, i1 cannot point to -1 unless the array is empty.
i2 can point to -1 if all elements are the same.
#include <stdio.h>
void get2(int a[], int n, int* i1, int* i2)
{
/* Transform from encoded n to actual length */
int m = -n-1;
/* Is this the first call? */
if (n >= 0)
{
/* Initialize the pointer to -1, i.e. no elements */
*i1 = *i2 = -1;
/* Start the recursion, encode the length */
get2(a, -n-1, i1, i2);
}
/* Here we are in the subsequent calls, we use m and not n */
else if (m-- > 0)
{
/* Assign i1 */
if (*i1 == -1 || a[m] > a[*i1])
{
*i2 = *i1; /* Don't forget to update i2 too! */
*i1 = m;
}
/* Opportunity to assign i2, check that the second max != max */
else if ((*i2 == -1 || a[m] > a[*i2]) && a[m] != a[*i1])
{
*i2 = m;
}
/* Tail recursion, do proper encoding of the n parameter */
get2(a, -m-1, i1, i2);
}
}
This function can be tested with this code
void test(int a[], int n)
{
int max, smax, i;
get2(a, n, &max, &smax);
printf("------------------------------\n");
for (i = 0; i < n; i++)
printf("%d ", a[i]);
printf("\nMax is ");
if (max >= 0)
printf("%d", a[max]);
else
printf("NOT FOUND");
printf("\nSecond Max is ");
if (smax >= 0)
printf("%d\n", a[smax]);
else
printf("NOT FOUND\n");
}
int main()
{
int v1[] = {};
int v2[] = {1};
int v3[] = {1,2};
int v4[] = {2, 1};
int v5[] = {2, 2};
int v6[] = {1,2,3,4};
int v7[] = {4,3,2,1};
int v8[] = {2,1,4,3};
int v9[] = {2,2,2,2};
int v10[] = {1,2,3,4,3,2,1};
int v11[] = {1,1,2,3,4,4};
test(v1, 0);
test(v2, 1);
test(v3, 2);
test(v4, 2);
test(v5, 2);
test(v6, 4);
test(v7, 4);
test(v8, 4);
test(v9, 4);
test(v10, 7);
test(v11, 6);
return 0;
}
With the below output
------------------------------
Max is NOT FOUND
Second Max is NOT FOUND
------------------------------
1
Max is 1
Second Max is NOT FOUND
------------------------------
1 2
Max is 2
Second Max is 1
------------------------------
2 1
Max is 2
Second Max is 1
------------------------------
2 2
Max is 2
Second Max is NOT FOUND
------------------------------
1 2 3 4
Max is 4
Second Max is 3
------------------------------
4 3 2 1
Max is 4
Second Max is 3
------------------------------
2 1 4 3
Max is 4
Second Max is 3
------------------------------
2 2 2 2
Max is 2
Second Max is NOT FOUND
------------------------------
1 2 3 4 3 2 1
Max is 4
Second Max is 3
------------------------------
1 1 2 3 4 4
Max is 4
Second Max is 3
I will give you another hint instead of writing the actual code for you:
You have 4 arguments, use all of them to pass the relevant data to the recursive calls. What I mean by that is - the first 2 arguments can describe the part of the array that is interesting for us, the pointers store the largest integers we have found, you modify them each time you find a bigger one.
And here lies the trap that most likely caught you - those are int *, that is a pointer to an integer. What the function receives is simply an address in memory. If you set that pointer to point to anything, the caller will not receive that data. You can simply write directly to that address instead of setting the pointer, like so:
int myInteger;
int *ptr = &myInteger;
*ptr = 123;
Here is a non-threadsafe way to do it: by keeping track of the original start of the array using a static variable. The addresses of the largest elements are stored in the pointers, which are used as pointers to pointers, and right at the end they are replaced by the indexes of the elements by using some pointer arithmetic aided by the static variable.
void get2(int a[], int n, int *one, int *two) {
static int *arr_start = 0;
if (n > 0) {
if (arr_start == 0) {
arr_start = a;
}
if (a[0] > **((int **)one)) {
*one = a;
} else if (a[0] > **((int **)two)) {
*two = a;
}
get2(a + 1, n - 1, one, two);
} else {
*one = *((int **)one) - arr_start;
*two = *((int **)two) - arr_start;
}
}
EDIT
Without using static variables: Use the second pointer as an indicator of whether or not we have already allocated space to keep track of the the start of the array and the indexes. Use the allocated space to keep track of the initial array size and the two largest indexes, then assign them to the correct pointers at the end:
#include <stdlib.h>
void get2(int a[], int n, int *one, int *two) {
int **pp_one = (int **)one;
if (*two != NULL) {
*pp_one = malloc(sizeof(int) * 3);
(*pp_one)[0] = n;
(*pp_one)[1] = 0;
(*pp_one)[2] = 0;
}
if (n > 0) {
if (a[0] > (*pp_one)[1]) {
(*pp_one)[1] = a;
} else if (a[0] > (*pp_one)[2]) {
(*pp_one)[2] = a;
}
get2(a + 1, n - 1, one, two);
} else {
int *t = *one;
*two = (*pp_one)[1] - (*pp_one)[0];
*one = (*pp_one)[2] - (*pp_one)[0];
free(t);
}
}
Thanks for the brain teaser. It sounded like an interesting problem. Even though it's homework, I decided to solve it.
This gets a bit annoying to do without having the indices pre-initialized somehow, but it's doable. Sounds like an artificial restriction to create artificial pain.
void
get2(int a[], int n, int *i1, int *i2) {
if (n == 0) {
*i1 = *i2 = -1;
return;
}
get2(&a[1], n - 1, i1, i2);
if (*i1 != -1)
(*i1)++;
if (*i2 != -1)
(*i2)++;
if (*i1 == -1) {
*i1 = 0;
} else if (*i2 == -1 || a[*i2] < a[0]) {
*i2 = 0;
if (a[*i1] < a[0]) {
*i2 = *i1;
*i1 = 0;
}
}
}
Here we just recurse until we have no array left to look at, then initialize the indices and on the way back we figure out the indices we're interested in. On the way back through all the recursions we update the indices i1 and i2 if they are initialized to properly point into the array we have in this iteration, then if i1 isn't initialized yet, then we know that n == 0 and must be the biggest element. On iterations after that we know that is the only interesting element of the array is element 0, if that's not bigger than a[*i2], then it's not bigger than a[*i1] either. If it is (or we're just initializing i2), we compare to see if we need to swap i1 and i2.
"But wait!", you might yell. "You're not doing tail recursion, if the array is massive you will run out of stack.". Glad you mentioned it, in fact, C doesn't say anything about the compiler having to do optimizations for tail recursion so I'd like to argue that any solution has to account for this problem. Here's a solution that works on the same principles (run out of array before we initialize the indices) that solves this in O(log n) stack space:
void
get2(int a[], int n, int *i1, int *i2) {
/*
* Reset the indices at the end of the recursion.
*/
switch (n) {
case 0:
*i1 = -1;
*i2 = -1;
return;
case 1:
*i1 = 0;
*i2 = -1;
return;
}
/*
* Number of elements in the lower and upper halves of the array.
* Notice the '+ (n & 1)' which is there to add one element to the
* upper half of the array if n is odd.
*
* The asserts document the invariants.
*/
int lower_half = n / 2, upper_half = (n / 2) + (n & 1);
int li1, li2, ui1, ui2;
assert(lower_half >= 1);
assert(upper_half >= 1);
assert(lower_half + upper_half == n);
get2(&a[0], n - upper_half, &li1, &li2);
get2(&a[lower_half], n - lower_half, &ui1, &ui2);
ui1 += lower_half;
if (ui2 != -1)
ui2 += lower_half;
assert(li1 != -1);
assert(ui1 != -1);
assert(li2 == -1 || a[li2] < a[li1]);
assert(ui2 == -1 || a[ui2] < a[ui1]);
if (a[li1] < a[ui1]) {
*i1 = ui1;
if (ui2 == -1 || a[li1] > a[ui2])
*i2 = li1;
else
*i2 = ui2;
} else if (a[li1] > a[ui1]) {
*i1 = li1;
if (li2 == -1 || a[ui1] > a[li2])
*i2 = ui1;
else
*i2 = li2;
} else {
*i1 = li1;
if (li2 == -1 || a[ui2] > a[li2])
*i2 = ui2;
else
*i2 = li2;
}
}
I'm not going to explain it, the comments and asserts should be enough to show what's going on. I'm pretty sure that the big block of ifs at the end can be written much more efficiently, but I didn't bother.
It might not be perfectly correct, it worked on the first try with a few test cases taken from the previous answers and I didn't do more testing. There might be some edge cases I haven't considered, but the general idea works.
Here is a nice answer I got. The next few strokes are just to get enough characters to publish my answer with this image. this it requieres 30 characters, so i wiil write anything.
It's brilliant as simple as it is. Isnt it ))?
* This code need a little correction, with one more condition, if one of the pointers is NULL, not to loop.
Here's my take on it. This implementation is pretty concise.
void get2(int a[], int n, int *i1, int *i2)
{
if (n == 0) return;
if (*i1 == -1 || a[n-1] > a[*i1]) {
*i2 = *i1;
*i1 = n-1;
} else if (*i2 == -1 || a[n-1] > a[*i2]) {
*i2 = n-1;
}
get2(a, n-1, i1, i2);
}
To test:
#define NUM 10
int main()
{
int a[NUM];
int i, i1, i2;
srand(time(NULL));
for (i=0;i<NUM;i++) {
a[i] = rand() & 0xFFFF;
fprintf(stderr,"%d ",a[i]);
}
fprintf(stderr,"\n");
i1 = i2 = -1;
get2(a,NUM,&i1,&i2);
fprintf(stderr,"i1=%d, i2=%d\n", i1, i2);
fprintf(stderr,"a[i1]=%d, a[i2]=%d\n", a[i1], a[i2]);
}
Just another try on your function prototype,
void get2(int a[], int n, int *i1, int *i2)
{
if(n <= 0)
return;
if(*i1 == -1 && n < 2){//initial a[] is null or with only one element
*i1 = n-1;
return;
}
if(*i1 == -1 && n >=2){
if(a[n-1] > a[n-2]){
*i1 = n-1;
*i2 = n-2;
}else{
*i1 = n-2;
*i2 = n-1;
}
return get2(a, n-2, i1, i2);
}
int max= a[*i1], less = a[*i2];
if(a[n-1] > max){
*i2 = *i1;
*i1 = n-1;
}else if (a[n-1] > less){
*i2 = n-1;
}
get2(a, n-1, i1, i2);
}
Test as follows,
int main()
{
int a[] = { 1, 2, 3, 4, 7, 8, 6, 5, 0};
int maxIndex = -1, lessIndex= -1;
get2(a,sizeof(a)/sizeof(int),&maxIndex,&lessIndex);
printf("maxIndex=%d(value:%d), lessIndex=%d(value:%d)\n",
maxIndex,a[maxIndex],lessIndex, a[lessIndex]);
}
Output,
maxIndex=5(value:8), lessIndex=4(value:7)
So I have an assignment where I need to change certain functions by substituting pointer operations for array operations, and by substituting string operations for character operations. Now I have a basic understanding of pointers, arrays, strings, etc. but I cant understand what it is I have to do, and how I should go about doing it. Here is the code:
#include <stdio.h>
#pragma warning(disable: 4996)
// This program exercises the operations of pointers and arrays
#define maxrow 50
#define maxcolumn 50
char maze[maxrow][maxcolumn]; // Define a static array of arrays of characters.
int lastrow = 0;
// Forward Declarations
#define triple(x) x % 3 == 0
void initialization(int, int);
void randommaze(int, int);
void printmaze(int, int);
void initialization(int r, int c) {
int i, j;
for (i = 0; i < r; i++){
maze[i][0] = 'X'; // add border
maze[i][c - 1] = 'X'; // add border
maze[i][c] = '\0'; // add string terminator
for (j = 1; j < c - 1; j++)
{
if ((i == 0) || (i == r - 1))
maze[i][j] = 'X'; // add border
else
maze[i][j] = ' '; // initialize with space
}
}
}
// Add 'X' into the maze at random positions
void randommaze(int r, int c) {
int i, j, d;
for (i = 1; i < r - 1; i++) {
for (j = 1; j < c - 2; j++) {
d = rand();
if (triple(d))
{
maze[i][j] = 'X';
}
}
}
i = rand() % (r - 2) + 1;
j = rand() % (c - 3) + 1;
maze[i][j] = 'S'; // define Starting point
do
{
i = rand() % (r - 2) + 1;
j = rand() % (c - 3) + 1;
} while (maze[i][j] == 'S');
maze[i][j] = 'G'; // define Goal point
}
// Print the maze
void printmaze(int r, int c) {
int i, j;
for (i = 0; i < r; i++) {
for (j = 0; j < c; j++)
printf("%c", maze[i][j]);
printf("\n");
}
}
void main() {
int row, column;
printf("Please enter two integers, which must be greater than 3 and less than maxrow and maxcolomn, respectively\n");
scanf("%d\n%d", &row, &column);
while ((row <= 3) || (column <= 3) || (row >= maxrow) || (column >= maxcolumn)) {
printf("both integers must be greater than 3. Row must be less than %d, and column less than %d. Please reenter\n", maxrow, maxcolumn);
scanf("%d\n%d", &row, &column);
}
initialization(row, column);
randommaze(row, column);
printmaze(row, column);
//encryptmaze(row, column);
//printmaze(row, column);
//decryptmaze(row, column);
//printmaze(row, column);
}
Here are the questions I am struggling on:
Rewrite the function randommaze(row, column) by substituting pointer operations for all array operations. You may not use indexed operation like maze[i][j], except getting the initial value of the pointer.
Rewrite the function printmaze(row, column) by substituting string operations for all character operations.
If someone could please explain to me what I should be doing and how I should be doing it I would really appreciate it. Thanks!
Question 2.:
An array can be used as a pointer to it's first member. So, for example, array[0] and *array return the same thing - the value of the first element of the array. Since arrays are contiguous blocks of memory, if you increment (or add an offset to) a pointer that's pointing to the beginning of an array, you point to the next element of the array. That means that array[1] and *(array + 1) are the same thing.
If you a have a for loop that iterates indexing an array, you could just as well write it using pointer increments. Example:
/* Loop indexing an array */
int my_array [10];
int i = 0;
for(; i < 10; ++i) {
my_array[i] = 0;
}
/* Loop by offsetting a pointer */
int my_array [10];
int i = 0;
int *ptr = my_array; /* Make it point to the first member of the array*/
for(; i < 10; ++i) [
*(ptr + i) = 0;
}
/* Looping by incrementing the pointer */
int my_array [10];
int *ptr = my_array; /* Make it point to the first member of the array */
int *end_ptr = my_array + 10; /* Make a pointer pointing to one past the end of the array */
for(; ptr != end; ++ptr) [
*ptr = 0;
}
All these code examples do the same thing. Assign 0 to all members of the array. If you a have a multidimensional array, just remember that it's still just a contiguous block of memory.
Question 3.:
This question is not so clear to me, so my interpretation of what you're expected to do may be a bit off, but since you're just using printf to print single chars, I'm guessing that you should use a function to output a single char instead. Something like putchar.
Hopefully, this will steer you in the right direction.
It sounds as though you are engaged in a data structures course. The first challenge is to build an array mapping function. For example:
int main(int argc, char **argv)
{
int values[20][40];
values[0][0] = 1;
values[10][10] = 20;
/* Let's print these two ways */
printf("0,0: %d 10,10: %d\n", values[0][0], values[10][10]);
printf("0,0: %d 10,10: %d\n", *((*values) + (sizeof(int) * 0) + sizeof(int) * 0)), *((*values) + (sizeof(int) * 10) + sizeof(int) * 10)));
}
What we are doing is obtaining the address of the very first byte of memory in the 2d array (*values) and then adding a raw number of bytes as an offset to it to locate the value from the "array" that we'd like to access.
One of the main points of an exercise like this is to show you how the language actually works under the hood. This his how array mapping functions work generally and can be used as the basis, for example, for a language or compiler design course later, in addition to fast implementations of far more complex memory structures.
As to the second piece, I'm not super clear on this since there are no actual "string" operations built into C. I'd need a bit more detail there.
I have the input as array A = [ 2,3,4,1]
The output is simply all possible permutation from elements in A which can be done by single transposition (single flip of two neighbouring elements) operation. So the output is :
[3,2,4,1],[ 2,4,3,1],[2,3,1,4],[1,3,4,2]
Circular transpositioning is allowed. Hence [2,3,4,1] ==> [1,3,4,2] is allowed and a valid output.
How to do it in C?
EDIT
In python, it would be done as follows:
def Transpose(alist):
leveloutput = []
n = len(alist)
for i in range(n):
x=alist[:]
x[i],x[(i+1)%n] = x[(i+1)%n],x[i]
leveloutput.append(x)
return leveloutput
This solution uses dynamic memory allocation, this way you can do it for an array of size size.
int *swapvalues(const int *const array, size_t size, int left, int right)
{
int *output;
int sotred;
output = malloc(size * sizeof(int));
if (output == NULL) /* check for success */
return NULL;
/* copy the original values into the new array */
memcpy(output, array, size * sizeof(int));
/* swap the requested values */
sotred = output[left];
output[left] = output[right];
output[right] = sotred;
return output;
}
int **transpose(const int *const array, size_t size)
{
int **output;
int i;
int j;
/* generate a swapped copy of the array. */
output = malloc(size * sizeof(int *));
if (output == NULL) /* check success */
return NULL;
j = 0;
for (i = 0 ; i < size - 1 ; ++i)
{
/* allocate space for `size` ints */
output[i] = swapvalues(array, size, j, 1 + j);
if (output[i] == NULL)
goto cleanup;
/* in the next iteration swap the next two values */
j += 1;
}
/* do the same to the first and last element now */
output[i] = swapvalues(array, size, 0, size - 1);
if (output[i] == NULL)
goto cleanup;
return output;
cleanup: /* some malloc call returned NULL, clean up and exit. */
if (output == NULL)
return NULL;
for (j = i ; j >= 0 ; j--)
free(output[j]);
free(output);
return NULL;
}
int main()
{
int array[4] = {2, 3, 4, 1};
int i;
int **permutations = transpose(array, sizeof(array) / sizeof(array[0]));
if (permutations != NULL)
{
for (i = 0 ; i < 4 ; ++i)
{
int j;
fprintf(stderr, "[ ");
for (j = 0 ; j < 4 ; ++j)
{
fprintf(stderr, "%d ", permutations[i][j]);
}
fprintf(stderr, "] ");
free(permutations[i]);
}
fprintf(stderr, "\n");
}
free(permutations);
return 0;
}
Although some people think goto is evil, this is a very nice use for it, don't use it to control the flow of your program (for instance to create a loop), that is confusing. But for the exit point of a function that has to do several things before returning, it think it's actually a nice use, it's my opinion, for me it makes the code easier to understand, I might be wrong.
Have a look at this code I have written with an example :
void transpose() {
int arr[] = {3, 5, 8, 1};
int l = sizeof (arr) / sizeof (arr[0]);
int i, j, k;
for (i = 0; i < l; i++) {
j = (i + 1) % l;
int copy[l];
for (k = 0; k < l; k++)
copy[k] = arr[k];
int t = copy[i];
copy[i] = copy[j];
copy[j] = t;
printf("{%d, %d, %d, %d}\n", copy[0], copy[1], copy[2], copy[3]);
}
}
Sample Output :
{5, 3, 8, 1}
{3, 8, 5, 1}
{3, 5, 1, 8}
{1, 5, 8, 3}
A few notes:
a single memory block is preferred to, say, an array of pointers because of better locality and less heap fragmentation;
the cyclic transposition is only one, it can be done separately, thus avoiding the overhead of the modulo operator in each iteration.
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int *single_transposition(const int *a, unsigned int n) {
// Output size is known, can use a single allocation
int *out = malloc(n * n * sizeof(int));
// Perform the non-cyclic transpositions
int *dst = out;
for (int i = 0; i < n - 1; ++i) {
memcpy(dst, a, n * sizeof (int));
int t = dst[i];
dst[i] = dst[i + 1];
dst[i + 1] = t;
dst += n;
}
// Perform the cyclic transposition, no need to impose the overhead
// of the modulo operation in each of the above iterations.
memcpy(dst, a, n * sizeof (int));
int t = dst[0];
dst[0] = dst[n-1];
dst[n-1] = t;
return out;
}
int main() {include
int a[] = { 2, 3, 4, 1 };
const unsigned int n = sizeof a / sizeof a[0];
int *b = single_transposition(a, n);
for (int i = 0; i < n * n; ++i)
printf("%d%c", b[i], (i % n) == n - 1 ? '\n' : ' ');
free(b);
}
There are many ways to tackle this problem, and most important questions are: how you're going to consume the output and how variable is the size of the array. You've already said the array is going to be very large, therefore I assume memory, not CPU will be the biggest bottleneck here.
If output is going to be used only few times (especially just once), it'll may be best to use functional approach: generate every transposition on the fly, and never have more than one in memory at a time. For this approach many high level languages would work as well as (maybe sometimes even better than) C.
If size of the array is fixed, or semi-fixed (eg few sizes known at compile-time), you can define structures, using C++ templates at best.
If size is dynamic and you still want to have every transposition in memory then you should allocate one huge memory block and treat it as contiguous array of arrays. This is very simple and straightforward on machine level. Unfortunately it's best tackled using pointer arithmetic, one feature of C/C++ that is renowned for being difficult to understand. (It isn't if you learn C from basics, but people jumping down from high level languages have proven track record of getting it completely wrong first time)
Other approach is to have big array of pointers to smaller arrays, which results in double pointer, the ** which is even more terrifying to newcomers.
Sorry for long post which is not a real answer, but IMHO there are too many questions left open for choosing the best solution and I feel you need bit more C basic knowledge to manage them on your own.
/edit:
As other solutions are already posted, here's a solution with minimum memory footprint. This is the most limiting approach, it uses same one buffer over and over, and you must be sure that your code is finished with first transposition before moving on to the next one. On the bright side, it'll still work just fine when other solutions would require terabyte of memory. It's also so undemanding that it might be as well implemented with a high level language. I insisted on using C++ in case you would like to have more than one matrix at a time (eg comparing them OR running several threads concurrently).
#define NO_TRANSPOSITION -1
class Transposable1dMatrix
{
private:
int * m_pMatrix;
int m_iMatrixSize;
int m_iCurrTransposition;
//transposition N means that elements N and N+1 are swapped
//transpostion -1 means no transposition
//transposition (size-1) means cyclic transpostion
//as usual in C (size-1) is the last valid index
public:
Transposable1dMatrix(int MatrixSize)
{
m_iMatrixSize = MatrixSize;
m_pMatrix = new int[m_iMatrixSize];
m_iCurrTransposition = NO_TRANSPOSITION;
}
int* GetCurrentMatrix()
{
return m_pMatrix;
}
bool IsTransposed()
{
return m_iCurrTransposition != NO_TRANSPOSITION;
}
void ReturnToOriginal()
{
if(!IsTransposed())//already in original state, nothing to do here
return;
//apply same transpostion again to go back to original
TransposeInternal(m_iCurrTransposition);
m_iCurrTransposition = NO_TRANSPOSITION;
}
void TransposeTo(int TranspositionIndex)
{
if(IsTransposed())
ReturnToOriginal();
TransposeInternal(TranspositionIndex);
m_iCurrTransposition = TranspositionIndex;
}
private:
void TransposeInternal(int TranspositionIndex)
{
int Swap1 = TranspositionIndex;
int Swap2 = TranspositionIndex+1;
if(Swap2 == m_iMatrixSize)
Swap2 = 0;//this is the cyclic one
int tmp = m_pMatrix[Swap1];
m_pMatrix[Swap1] = m_pMatrix[Swap2];
m_pMatrix[Swap2] = tmp;
}
};
void main(void)
{
int arr[] = {2, 3, 4, 1};
int size = 4;
//allocate
Transposable1dMatrix* test = new Transposable1dMatrix(size);
//fill data
memcpy(test->GetCurrentMatrix(), arr, size * sizeof (int));
//run test
for(int x = 0; x<size;x++)
{
test->TransposeTo(x);
int* copy = test->GetCurrentMatrix();
printf("{%d, %d, %d, %d}\n", copy[0], copy[1], copy[2], copy[3]);
}
}
This question already has answers here:
nth fibonacci number in sublinear time
(16 answers)
Closed 6 years ago.
I am a CSE student and preparing myself for programming contest.Now I am working on Fibonacci series. I have a input file of size about some Kilo bytes containing positive integers. Input formate looks like
3 5 6 7 8 0
A zero means the end of file. Output should like
2
5
8
13
21
my code is
#include<stdio.h>
int fibonacci(int n) {
if (n==1 || n==2)
return 1;
else
return fibonacci(n-1) +fibonacci(n-2);
}
int main() {
int z;
FILE * fp;
fp = fopen ("input.txt","r");
while(fscanf(fp,"%d", &z) && z)
printf("%d \n",fibonacci(z));
return 0;
}
The code works fine for sample input and provide accurate result but problem is for my real input set it is taking more time than my time limit. Can anyone help me out.
You could simply use a tail recursion version of a function that returns the two last fibonacci numbers if you have a limit on the memory.
int fib(int n)
{
int a = 0;
int b = 1;
while (n-- > 1) {
int t = a;
a = b;
b += t;
}
return b;
}
This is O(n) and needs a constant space.
You should probably look into memoization.
http://en.wikipedia.org/wiki/Memoization
It has an explanation and a fib example right there
You can do this by matrix multiplictation, raising the matrix to power n and then multiply it by an vector. You can raise it to power in logaritmic time.
I think you can find the problem here. It's in romanian but you can translate it with google translate. It's exactly what you want, and the solution it's listed there.
Your algorithm is recursive, and approximately has O(2^N) complexity.
This issue has been discussed on stackoverflow before:
Computational complexity of Fibonacci Sequence
There is also a faster implementation posted in that particular discussion.
Look in Wikipedia, there is a formula that gives the number in the Fibonacci sequence with no recursion at all
Use memoization. That is, you cache the answers to avoid unnecessary recursive calls.
Here's a code example:
#include <stdio.h>
int memo[10000]; // adjust to however big you need, but the result must fit in an int
// and keep in mind that fibonacci values grow rapidly :)
int fibonacci(int n) {
if (memo[n] != -1)
return memo[n];
if (n==1 || n==2)
return 1;
else
return memo[n] = fibonacci(n-1) +fibonacci(n-2);
}
int main() {
for(int i = 0; i < 10000; ++i)
memo[i] = -1;
fibonacci(50);
}
Nobody mentioned the 2 value stack array version, so I'll just do it for completeness.
// do not call with i == 0
uint64_t Fibonacci(uint64_t i)
{
// we'll only use two values on stack,
// initialized with F(1) and F(2)
uint64_t a[2] = {1, 1};
// We do not enter loop if initial i was 1 or 2
while (i-- > 2)
// A bitwise AND allows switching the storing of the new value
// from index 0 to index 1.
a[i & 1] = a[0] + a[1];
// since the last value of i was 0 (decrementing i),
// the return value is always in a[0 & 1] => a[0].
return a[0];
}
This is a O(n) constant stack space solution that will perform slightly the same than memoization when compiled with optimization.
// Calc of fibonacci f(99), gcc -O2
Benchmark Time(ns) CPU(ns) Iterations
BM_2stack/99 2 2 416666667
BM_memoization/99 2 2 318181818
The BM_memoization used here will initialize the array only once and reuse it for every other call.
The 2 value stack array version performs identically as a version with a temporary variable when optimized.
You can also use the fast doubling method of generating Fibonacci series
Link: fastest-way-to-compute-fibonacci-number
It is actually derived from the results of the matrix exponentiation method.
Use the golden-ratio
Build an array Answer[100] in which you cache the results of fibonacci(n).
Check in your fibonacci code to see if you have precomputed the answer, and
use that result. The results will astonish you.
Are you guaranteed that, as in your example, the input will be given to you in ascending order? If so, you don't even need memoization; just keep track of the last two results, start generating the sequence but only display the Nth number in the sequence if N is the next index in your input. Stop when you hit index 0.
Something like this:
int i = 0;
while ( true ) {
i++; //increment index
fib_at_i = generate_next_fib()
while ( next_input_index() == i ) {
println fib_at_i
}
I leave exit conditions and actually generating the sequence to you.
In C#:
static int fib(int n)
{
if (n < 2) return n;
if (n == 2) return 1;
int k = n / 2;
int a = fib(k + 1);
int b = fib(k);
if (n % 2 == 1)
return a * a + b * b;
else
return b * (2 * a - b);
}
Matrix multiplication, no float arithmetic, O(log N) time complexity assuming integer multiplication/addition is done in constant time.
Here goes python code
def fib(n):
x,y = 1,1
mat = [1,1,1,0]
n -= 1
while n>0:
if n&1==1:
x,y = x*mat[0]+y*mat[1], x*mat[2]+y*mat[3]
n >>= 1
mat[0], mat[1], mat[2], mat[3] = mat[0]*mat[0]+mat[1]*mat[2], mat[0]*mat[1]+mat[1]*mat[3], mat[0]*mat[2]+mat[2]*mat[3], mat[1]*mat[2]+mat[3]*mat[3]
return x
You can reduce the overhead of the if statement: Calculating Fibonacci Numbers Recursively in C
First of all, you can use memoization or an iterative implementation of the same algorithm.
Consider the number of recursive calls your algorithm makes:
fibonacci(n) calls fibonacci(n-1) and fibonacci(n-2)
fibonacci(n-1) calls fibonacci(n-2) and fibonacci(n-3)
fibonacci(n-2) calls fibonacci(n-3) and fibonacci(n-4)
Notice a pattern? You are computing the same function a lot more times than needed.
An iterative implementation would use an array:
int fibonacci(int n) {
int arr[maxSize + 1];
arr[1] = arr[2] = 1; // ideally you would use 0-indexing, but I'm just trying to get a point across
for ( int i = 3; i <= n; ++i )
arr[i] = arr[i - 1] + arr[i - 2];
return arr[n];
}
This is already much faster than your approach. You can do it faster on the same principle by only building the array once up until the maximum value of n, then just print the correct number in a single operation by printing an element of your array. This way you don't call the function for every query.
If you can't afford the initial precomputation time (but this usually only happens if you're asked for the result modulo something, otherwise they probably don't expect you to implement big number arithmetic and precomputation is the best solution), read the fibonacci wiki page for other methods. Focus on the matrix approach, that one is very good to know in a contest.
#include<stdio.h>
int g(int n,int x,int y)
{
return n==0 ? x : g(n-1,y,x+y);}
int f(int n)
{
return g(n,0,1);}
int main (void)
{
int i;
for(i=1; i<=10 ; i++)
printf("%d\n",f(i)
return 0;
}
In the functional programming there is a special algorithm for counting fibonacci. The algorithm uses accumulative recursion. Accumulative recursion are used to minimize the stack size used by algorithms. I think it will help you to minimize the time. You can try it if you want.
int ackFib (int n, int m, int count){
if (count == 0)
return m;
else
return ackFib(n+m, n, count-1);
}
int fib(int n)
{
return ackFib (0, 1, n+1);
}
use any of these: Two Examples of recursion, One with for Loop O(n) time and one with golden ratio O(1) time:
private static long fibonacciWithLoop(int input) {
long prev = 0, curr = 1, next = 0;
for(int i = 1; i < input; i++){
next = curr + prev;
prev = curr;
curr = next;
}
return curr;
}
public static long fibonacciGoldenRatio(int input) {
double termA = Math.pow(((1 + Math.sqrt(5))/2), input);
double termB = Math.pow(((1 - Math.sqrt(5))/2), input);
double factor = 1/Math.sqrt(5);
return Math.round(factor * (termA - termB));
}
public static long fibonacciRecursive(int input) {
if (input <= 1) return input;
return fibonacciRecursive(input - 1) + fibonacciRecursive(input - 2);
}
public static long fibonacciRecursiveImproved(int input) {
if (input == 0) return 0;
if (input == 1) return 1;
if (input == 2) return 1;
if (input >= 93) throw new RuntimeException("Input out of bounds");
// n is odd
if (input % 2 != 0) {
long a = fibonacciRecursiveImproved((input+1)/2);
long b = fibonacciRecursiveImproved((input-1)/2);
return a*a + b*b;
}
// n is even
long a = fibonacciRecursiveImproved(input/2 + 1);
long b = fibonacciRecursiveImproved(input/2 - 1);
return a*a - b*b;
}
using namespace std;
void mult(LL A[ 3 ][ 3 ], LL B[ 3 ][ 3 ]) {
int i,
j,
z;
LL C[ 3 ][ 3 ];
memset(C, 0, sizeof( C ));
for(i = 1; i <= N; i++)
for(j = 1; j <= N; j++) {
for(z = 1; z <= N; z++)
C[ i ][ j ] = (C[ i ][ j ] + A[ i ][ z ] * B[ z ][ j ] % mod ) % mod;
}
memcpy(A, C, sizeof(C));
};
void readAndsolve() {
int i;
LL k;
ifstream I(FIN);
ofstream O(FOUT);
I>>k;
LL A[3][3];
LL B[3][3];
A[1][1] = 1; A[1][2] = 0;
A[2][1] = 0; A[2][2] = 1;
B[1][1] = 0; B[1][2] = 1;
B[2][1] = 1; B[2][2] = 1;
for(i = 0; ((1<<i) <= k); i++) {
if( k & (1<<i) ) mult(A, B);
mult(B, B);
}
O<<A[2][1];
}
//1,1,2,3,5,8,13,21,33,...
int main() {
readAndsolve();
return(0);
}
public static int GetNthFibonacci(int n)
{
var previous = -1;
var current = 1;
int element = 0;
while (1 <= n--)
{
element = previous + current;
previous = current;
current = element;
}
return element;
}
This is similar to answers given before, but with some modifications. Memorization, as stated in other answers, is another way to do this, but I dislike code that doesn't scale as technology changes (size of an unsigned int varies depending on the platform) so the highest value in the sequence that can be reached may also vary, and memorization is ugly in my opinion.
#include <iostream>
using namespace std;
void fibonacci(unsigned int count) {
unsigned int x=0,y=1,z=0;
while(count--!=0) {
cout << x << endl; // you can put x in an array or whatever
z = x;
x = y;
y += z;
}
}
int main() {
fibonacci(48);// 48 values in the sequence is the maximum for a 32-bit unsigend int
return 0;
}
Additionally, if you use <limits> its possible to write a compile-time constant expression that would give you the largest index within the sequence that can be reached for any integral data type.
#include<stdio.h>
main()
{
int a,b=2,c=5,d;
printf("%d %d ");
do
{
d=b+c;
b=c;
c=d;
rintf("%d ");
}