This book requires me to answer '' What output do you expect from the following program?''
After reading it many times I dont seem to fully understand its inner workings.
From what I get:
First For loop stablishes that this process is going to repeat for 10 times. Variable j is assigned to start at 0.
Second for loop starts the variable i at 0 and stablishes the condition i < j and does the operations written after it.
What is going on exactly? j starts at 0 and so does i, therefore numbers[j] += numbers[i] equals 2?
What happens after this operation is completed?
If i and j equal to 0 then why is this condition i < j True?
int main (void)
{
int numbers[10] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int i, j;
for ( j = 0; j < 10; ++j )
for ( i = 0; i < j; ++i )
numbers[j] += numbers[i];
for ( j = 0; j < 10; ++j )
printf ("%i ", numbers[j]);
printf ("\n");
return 0;
}
The first thing you have to notice is that you have the outer loop, which runs from 0 to 10 and you to something to numbers[j]. This indicates that you take each element and modify it somehow. In order to find how, by inspecting the second loop and the right hand side of the assignment, you can notice that it adds to numbers[j] all elements with indices smaller than j. Now let's see what happens in a few steps:
j = 0 : 1 0 0 0 0 0 0 0 0 0
j = 1 : 1 1 0 0 0 0 0 0 0 0
j = 2 : 1 1 2 0 0 0 0 0 0 0
j = 3 : 1 1 2 4 0 0 0 0 0 0
j = 4 : 1 1 2 4 8 0 0 0 0 0
At the end, you will get an array with the property that each element a[j] is equal to a[0] + a[1] + ... + a[j] and a[0] = 1.
Now, taking a closer look at the beginning of the process, you have j = 0 and i = 0. The second for loop runs for as long as i < j. Since this comparison is false, the loop is not executed and we go to the next iteration of the outer loop, with j = 1.
Related
I am trying to make a game of checkers, and right now I'm building the board. The board is a 2-dimensional array of integers that I'm changing based on where the pieces should be.
// Sets up Red Pieces
int k = 0;
for (i = 0; i < 3; i++)
{
for (j = k; j < 8; j += 2)
{
// Red piece is on square at coords [i][j]
Board_Squares[i][j] += 2;
}
printf("\n");
// k starts at 0, and in switch should alternate between 1 and 0,
switch (k)
{
case 0:
k = 1;
case 1:
k = 0;
}
}
However, this code only gives me this:
0 2 0 2 0 2 0
0 2 0 2 0 2 0
0 2 0 2 0 2 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
Any help would be dope. Warning: I might be dumb.
Also, is using the switch statement the right move here anyways?
the problem in your code comes from missing break statements: the code for a case fall through to the code for the next case.
Modify it this way:
switch (k) {
case 0:
k = 1;
break;
case 1:
k = 0;
break;
}
The same toggling effect can be obtained with simple expressions:
k = 1 - k;
k ^= 1;
k = !k;
k = k == 0;
Or some more convoluted and obscure ones:
k = !!!k;
k = k ? 0 : 1;
k = (k + 1) & 1;
k = "\1"[k];
k = k["\1"];
k = 1 / (1 + k);
The checker board cells can also be initialized directly to 0 and 1 as:
Board_Squares[i][j] = (i + j) & 1;
I have an array called int arr[10] = {1,2,3,4,5}
From my understanding the rest of the array is filled with 0's.
My questions is if its a fixed array length how can I put the first index behind the last index that is not a 0. For example
I believe the 0 is not shown in real printf but I am including it for illustration purposes
for (int i = 0 ; i < 10 ; i++)
{
print("%i" , arr[i]);
}
The output
1 2 3 4 5 0 0 0 0 0
If i move the first index to the back of the 5 like so
for (int i = -1 ; i < 10 ; i++)
{
arr[i] = arr[i + 1];
print("%i" , arr[i]);
}
Will the output put the 1 behind the 5 or at the back of the whole array?
2 3 4 5 1 0 0 0 0 0
or because there is 0s then
2 3 4 5 0 0 0 0 0 1
If my question is unclear please tell me and I will try explain it.
The output
1 2 3 4 5 0 0 0 0 0
No, the actual output is
1234500000
Your code has undefined behavior. The first iteration of the loop (with i = -1) tries to assign to arr[-1], which does not exist:
arr[i] = arr[i + 1];
Similarly, the last iteration (with i = 9) tries to read from arr[10], which also does not exist.
I'm not sure why you think your code will move the first element back.
From my understanding the rest of the array is filled with 0's
You are right.:)
If i move the first index to the back of the 5 like so
for (int i = -1 ; i < 10 ; i++)
{
arr[i] = arr[i + 1];
print("%i" , arr[i]);
}
then you will get undefined behavior because the indices -1 and 10 are not valid indices.
It seems what you are trying to do is the following
#include <stdio.h>
#include <string.h>
int main(void)
{
enum { N = 10 };
int a[N] = { 1, 2, 3, 4, 5 };
size_t pos = 0;
while ( pos < N && a[pos] != 0 ) ++pos;
if ( pos != N && !( pos < 3 ) )
{
int tmp = a[0];
pos -= 2;
memmove( a, a + 1, pos * sizeof( int ) );
a[pos] = tmp;
}
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
putchar( '\n' );
return 0;
}
The program output is
2 3 4 1 5 0 0 0 0 0
I'm trying to implement a two functions based on Depth First Search using a recursion method. I'm ultimately trying to compare the runtime against warshall's algorithm (which I already have working). When I print my matrix it's off by a couple off paths.
The recursion is what may be throwing me off, it's my weakness. Because of the top if statement if(iIndex1 == iIndex2) return TRUE;, when I try to find if there is a path from (A,A), (B,B), (C,C), etc. I will always get 1 even if there is no path from A to A.
typedef enum { FALSE, TRUE } bool;
/* Recursive function will determine if there is a path from index 1 to 2
* Based of DFS
*/
bool recPathExists( Graph G, int iIndex1, int iIndex2 )
{
int j;
G.nodeArray[iIndex1].visited = TRUE;
if(iIndex1 == iIndex2){
return TRUE;
}
for(j = 0; j < G.iNumNodes; j++){
if(!G.nodeArray[j].visited && G.adjMatrix[iIndex1][j]==1){
if(recPathExists(G, j, iIndex2))
return TRUE;
}
}
return FALSE;
}
/* Write a function to find all pairs of nodes which have paths between them.
* Store this information in the provided pathMatrix.
*/
void allPathsRecFunc( Graph G , int **pathMatrix )
{
int i, j;
for(i = 0; i < G.iNumNodes; i++){
for(j = 0; j < G.iNumNodes; j++){
if(recPathExists(G, i , j)== TRUE){
pathMatrix[i][j] = 1;
}
resetVisited(G); //resets all nodes to FALSE
}
}
}
what it should be
A 0 1 1 1 1 1 1 1
B 0 1 0 0 1 1 1 1
C 0 1 0 0 1 1 1 1
D 0 0 0 0 0 0 0 0
E 0 0 0 0 0 0 0 0
F 0 1 0 0 1 1 1 1
G 0 1 0 0 1 1 1 1
H 0 1 0 0 1 1 1 1
what I get
A 1 1 1 1 1 1 1 1
B 0 1 0 0 1 1 1 1
C 0 1 1 0 1 1 1 1
D 0 0 0 1 0 0 0 0
E 0 0 0 0 1 0 0 0
F 0 1 0 0 1 1 1 1
G 0 1 0 0 1 1 1 1
H 0 1 0 0 1 1 1 1
Your issue may be here:
for(j = 0; j < G.iNumNodes; j++)
{
if(!G.nodeArray[j].visited && G.adjMatrix[iIndex1][j] == 1)
{
return recPathExists(G, j, iIndex2);
}
}
By returning the result of recursing on recPathExists, you're not checking the other possible nodes that could be reachable in the loop (in essence, you're returning failure too early, and missing possible paths).
I believe you want just a little modification:
for(j = 0; j < G.iNumNodes; j++)
{
if(!G.nodeArray[j].visited && G.adjMatrix[iIndex1][j] == 1)
{
if (recPathExists(G, j, iIndex2))
return TRUE;
}
}
That is, "if a path does exist, return as we've found it. If not, keep looking".
My depth first search uses recursion but it outputs a parent array, though the functionality should be the same. It got a perfect grade so I know it works. Hope it helps.
https://github.com/grantSwalwell/Data-Structures/blob/master/Depth%20First%20Search.h
Algorithm~
bool array, visited for flagging nodes
search number array to measure the depth of access
depth to increment and come up with search num
Call DFS on 0,0
For each non visited neighbor
DFS depth + 1, search = depth, visited = true
return parent array, showing the search pattern
// Depth First Search recursive helper method
void DFS(Graph& G, int v0, Array<bool>* visited, Array<int>* search, int
depth)
{
// set visited
(*visited)[v0] = true;
// set search num
(*search)[v0] = depth;
// iterate through neighbors
for (int i = 0; i < G.nodes(); i++)
{
// if i is a neighbor
if (G.edge(i, v0))
{
// if it has not been visited
if (!(*visited)[i])
{
// call DFS
DFS(G, i, visited, search, depth + 1);
}
} // end if
} // end for
}
// Depth First Search
Array<int>* DFS(Graph& G, int v0)
{
// visited array
Array<bool>* visited = new Array<bool>(G.nodes());
// search number array, order of visitation
Array<int>* search = new Array<int>(G.nodes());
// initialize both arrays
for (int i = 0; i < G.nodes(); i++)
{
(*visited)[i] = false;
(*search)[i] = 1;
}
// create depth field
int depth = 1;
// call DFS
DFS(G, v0, visited, search, depth);
return search;
};
I have a 2D array storing image data using int. At this time it is 800x640 but that can change. I want to pass it to another function in 8x8 blocks for processing. I could actually just copy an 8x8 block of the array into a temporary variable and send that to the function and then copy result into another 800x640 array.
However, I want to the function to directly be able to access 8x8 blocks (which will be faster) if I give it the start xy coordinates within this 800x640 array. The problem is that using int** does not work. Also parameter declared as int[8][8] also does not compiled. What do I do? Right now I am writing the program in C++ but eventually shall have to write it in C as well.
You can give the pointer to the original image with other parameters to the function and access each element of your 8x8 area inside the function.
Let's say this is your original 800x640 image:
int img[640][800];
Declare your fuction as:
void work_on_roi(int* img, size_t img_width, size_t img_height, int roi_x, int roi_y, size_t roi_width, size_t roi_height)
ROI stands for region of interest, a widely used term in the field of image processing. In your case, if you want to access roi with (10,20) as its top-left index, you can call this function with arguments as:
work_on_roi(img, 800, 640, 10, 20, 8, 8)
Inside this function, accessing the (i,j) element in the roi would be:
(img + (roi_y + j) * img_width)[roi_x + i]
You can utilize roi_width and roi_height parameter to check for integrity:
// before accessing (i,j) element of roi
assert(i < roi_width);
assert(j < roi_height);
assert(roi_x + i < img_width);
assert(roi_y + j < img_height);
While the way you access the elements of the region will not change depending on how you have declared your array, the way you pass the array as a parameter will change depending on whether you have an actual 2D array or whether you have a pointer-to-pointer-to-type.
In the case of a true array declared similar to int array[X][Y]; (where X and Y are defined constants) you can pass a pointer to array of int [Y], (e.g. (*array)[Y]) as the parameter to your function.
In the case where array is will be converted to a pointer-to-pointer-to-type, when declared similar to int **array; or int (*array)[z]; where you allocate pointers and blocks of each row, or one single block, respectively, you simply pass a pointer-to-pointer-to-type (e.g. int **array)
Taking either case, you could change a region within the array with a simple function that iterates over the elements you wish to change. For example for the case where you have a 2D array as you specify, you could declare a function with logic similar to the following. (You could pass additional parameters as needed to effect whatever change you need)
enum { ROW = 10, COL = 10 }; /* constant definitions */
...
void chgregion (int (*a)[COL], int xs, int ys, int xn, int yn)
{
int xlim = xs + xn, /* xstart + xnumber_of_elements */
ylim = ys + yn; /* same for y */
if (xlim > ROW) xlim = ROW; /* protect array/block bounds */
if (ylim > COL) ylim = COL;
for (int i = xs; i < xlim; i++)
for (int j = ys; j < ylim; j++)
a[i][j] = 1; /* change element as required */
}
Above the a pointer to an array of COL elements is passed along with the x and y starting position within the array and the number of elements in the region, e.g. xn and yn. A simple check is done to limit the region size to remain within the array bounds or bounds of a block of memory. If your array is actually a pointer-to-pointer-to-type, just pass int **a instead and pass the dimensions of the block of memory as additional parameters.
You can put together a simple test as follows:
#include <stdio.h>
enum { ROW = 10, COL = 10 };
void chgregion (int (*a)[COL], int xs, int ys, int xn, int yn);
void prna (int (*a)[COL]);
int main (void) {
int a[ROW][COL] = {{0}};
prna (a);
chgregion (a, 2, 2, 6, 6);
putchar ('\n');
prna (a);
return 0;
}
void chgregion (int (*a)[COL], int xs, int ys, int xn, int yn)
{
int xlim = xs + xn,
ylim = ys + yn;
if (xlim > ROW) xlim = ROW;
if (ylim > COL) ylim = COL;
for (int i = xs; i < xlim; i++)
for (int j = ys; j < ylim; j++)
a[i][j] = 1;
}
void prna (int (*a)[COL])
{
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++)
printf ("%2d", a[i][j]);
putchar ('\n');
}
}
Example Use/Output
$ ./bin/array2d_region
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
Let me know if this is what you were intending, or if what you are doing differs in some way. For further help, please post a Minimal, Complete, and Verifiable example.
I would like to loop through two arrays in a semi-zipped fashion, such that for as many entries as possible, the following pattern is observed:
arr1[i] arr2[j]
arr1[i] arr2[j+1]
arr1[i+1] arr2[j+2]
arr1[i+1] arr2[j+3]
....
For example, if len arr1 is 96 and len arr2 is 3, I would like to see
0 0
0 1
1 2
1 0
2 1
2 2
3 0
3 1
4 2
4 0
5 1
5 2
I'm having a little trouble getting the logic exactly right; any help would be greatly appreciated
Pseudocode:
i = 0;
for (x = 0; i < arr1.len; ++x) {
i = x / 2; // integer division
j = x % arr2.len;
// use arr1[i] and arr2[j]
}
Use integer division to repeat a value multiple times before moving on to the next value (e.g. 0 0 1 1 2 2 3 3 ...), where the number of times you want to repeat a value is equal to the denominator.
Use modulo division to repeat a sequence of values indefinitely (e.g. 0 1 2 0 1 2 0 1 2 ...), where the number of items in the sequence is equal to the denominator.
If I have understood you correctly you need a loop like the one shown in the demonstrative program below.
#include <stdio.h>
#define N 10
#define M 3
int main( void )
{
int a[N];
int b[N];
for ( int i = 0; i < N; i++ ) a[i] = i;
for ( int i = 0; i < M; i++ ) b[i] = i;
for (int i = 0, j = 0, k = 1; i < N; i += k ^= 1, j = ( j + 1 ) % M)
{
printf( "%d %d\n", a[i] , b[j] );
}
}
The program output is
0 0
0 1
1 2
1 0
2 1
2 2
3 0
3 1
4 2
4 0
5 1
5 2
6 0
6 1
7 2
7 0
8 1
8 2
9 0
9 1