int tab[][3] = {
{1, 2, 3},
{6, 5, 4},
{7, 8, 9}
};
main(){
int i, j, t=0;
for(i=2, j=0; i; i--, j++){
t += tab[i][j++];
printf("%d", t);
}
I don't understand why the output is 11, firstly i = 2; (7, 8, 9) and j = 0 and then t += tab[i][j++] this means 7, 8, 9 + (j++ which is 1 now) (2, 5, 8) which means 7 + 8 + 9 + 2 + 5 + 8? I don't get this. t += tab[i][j++]
Two things:
First, it seems that you assume that t += tab[i][j] somehow adds a complete vector or a row to t, i.e. something like (7,8,9). Yet an access to tab[i][j] stands for one particular cell value (not a row), and with i==2, j==0, this means tab[2][0] and yields value 7.
Second, note that you have two statements that increment j, one in the for-part, and one in tab[i][j++] (note the j++). So when i decreases to 1, j has actually increased to 2, such that the second value will be tab[1][2], which is 4.
Then 7 + 4 = 11 should not be a surprise any longer :-).
Hope it helps.
First change printf() to printf("%d\n", t); to see each t value in one line.
running program produce this output:
as you see we have : 7 for first t,
before that you can use two simple for loop to print matrix all elements
and have better view on its elements order.
If you make for loop indentation better you can decode the output results.
grab a pen and paper and draw variables of loop in each iteration.
for(i=2, j=0 ; i != 0 ; i--, j++ ){
t += tab[i][j++];
printf("%d\n", t);
}
first iteration i:2 , j=0 as the condition i != 0(i.e i is not equals to 0 ) is true, then body of for is executed and we have t += tab[2][0];' 'tab [2][0] pointing to 7 (array index in C starts from Zero 0) and because of value of t is 0, now t holds 7 and simply printed on screen. after that j++ in the tab[i][j++] add one to j and now j:1 as this for iteration has been finished two commands in the third part of for is executed now (i--, j++) and make values to i:1 , j:2.
we start second for iteration.
as the condition i != 0 i still true we pass inside of for and
t += tab1[2]; tab[1][2] :4 and added to t:7 we have now t:7+4=11
and print t:11 on screen. now j added by one j:3 and this iteration is finished goto third part of for i--,j++ we have i:0, j:4.
in later iteration first we must check the for condition i != 0 as now i:0 this condition is False and obviously for is finished.
This is my version
int tab[][3] = {
{1, 2, 3},
{6, 5, 4},
{7, 8, 9}
};
//Main Program Function, Execution Part
int main()
{
int i, j, t=0;
for (int i=0;i<3;i++){
printf("\n");
for (int j=0;j<3;j++){
printf("%d\t", tab[i][j]);
}
}
printf("\n\n");
for(i=2, j=0 ; i != 0 ; i--, j++ ){
t += tab[i][j++];
printf("%d\n", t);
}
system ("pause");
}
Related
So for my coding class (in C), we had to write a program that would fill a square of N >=4 elements in a certain manner (from left to right and then down and then right to left to go up and end at the origin).
After a while, and getting a solution with layers repeating the set of instructions for each circle we get this program:
#include <stdio.h>
#define N 4
int main(void){
int map[N][N];
int dirs[4][2] = {
{0, 1},
{1, 0},
{0, -1},
{-1, 0}
};
for (int layer=0; layer < (N+1)/2; layer++){
// for each layer the starting point is (layer, layer)
// for each layer and each direction the number of repeat is N - layer*2 -1
int x=layer, y=layer;
int number = 1;
map[x][y] = number; // in case of N is odd
for (int dir=0; dir < 4; dir ++){
for (int i=0; i<N-layer*2-1; i++){
map[x][y] = number;
number ++;
x = x + dirs[dir][0];
y = y + dirs[dir][1];
}
}
}
printf("Final map is: \n");
for (int i = 0; i < N; i++){
for (int j = 0; j < N; j++){
printf("%4d ", map[i][j]);
}
printf("\n");
}
return 0;
}
Output:
Final map is:
1 2 3 4
12 1 2 5
11 4 3 6
10 9 8 7
Process finished with exit code 0
But I don't understand why do we put the supposed last instruction {0,1} (meaning go up 1 element and stay on said column) as the first instruction, considering we start counting from 1 and end up at 4 by repeating the {0,1} instruction N-layer*2-1 times (3 if n=4 and in the first layer).
Shouldn't dirs be:
int dirs[4][2] = {
{1, 0},
{0, -1},
{-1, 0},
{0, 1}
};
(0,1) means moving from column y=0 to column y=1 thus moving rightwards (ryyker's comment enlightens this).
Is it possible in C to have a fast for/while loop that loops through the odd numbers and 2? Without using arrays.
So I'd like it to loop through {1, 2, 3, 5, 7, 9, ..}
Of course. Here is a pretty straight forward way.
for(int i=1; i<N; i++) {
if(i>3) i++;
// Code
}
A bit more hackish variant:
for(int i=1; i<N; i+=1+(i>2)) {
// Code
}
But I think in this case that the most readable variant would be something like:
// Code for 1 and 2
// Then code for 3,5,7 ...
for(int i=3; i<N; i+=2) {
// Code
}
Another option
for(int i=1;;++i) // you didn't specify a limit
{
switch(i)
{
default:
if(!(i&1))continue;
case 1:
case 2:
DoSomething(i):
}
}
Another alternative which does use an array but only a small one that is a constant size of two elements no matter how many numbers in the sequence would be:
{
int i;
int iray[] = {1, 2};
int n = 15;
for (i = 1; i < n; i += iray[i > 2]) {
printf (" i = %d \n", i);
// code
}
}
which produces:
i = 1
i = 2
i = 3
i = 5
i = 7
i = 9
i = 11
i = 13
Extending this alternative to other sequences
And this alternative can be extended to other sequences where there is a change of a similar nature. For instance if the desired sequence was
1, 2, 3, 5, 8, 11, ..
Which involves several changes in the sequence. Beginning at 1 an increment of 1 is used followed by a first increment change beginning at 3 where an increment of 2 is used followed by a second change in the sequence beginning at 5 where an increment of 3 is used, you can make the following modification.
{
int i;
int iray[] = {1, 2, 3}; // increment changes
int n = 15;
// calculate the increment based on the current value of i
for (i = 1; i < n; i += iray[(i > 2) + (i > 3)]) {
printf (" i = %d \n", i);
// code
}
return 0;
}
which would produce:
i = 1
i = 2
i = 3
i = 5
i = 8
i = 11
i = 14
#include <stdio.h>
int main()
{
for(unsigned x = 0; x < 10; x++)
printf("%u%s element - %u\n",x + 1, !x ? "st" : x == 1 ? "nd" : x == 2 ? "rd" : "th", !x + x * 2 - (x >= 2));
return 0;
}
no jumps calculating in the !x + x * 2 - (x >= 2) so no pipeline flushes.
building a code that will check if a group of numbers in s_array[] is a sub-sequence of array[], that means that { 1, 5, 4 } is not a sub-sequence of array, whereas { 1, 4, 5} is one (order matters)
my code will first check if the first element of s_array[] exists in array[], once a common element is found it will proceed to check if the rest of s_array[]'s elements also exist in array[] and in the same order (other elements can be between them)
#include <stdio.h>
void main(){
int s_array[] = { 5, 7, 13 };
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
int i, Bcount, m, counter = 1, j = 4;
//i, Bcount and m are loop counters
//counter will count number of repeated elements
//j is the number of elements in s_array + 1
for( i = 0; i <= 15; i++ ){
if( s_array[0] == array[i] ){ // does the first element exist?
for( Bcount = 1; Bcount < j; Bcount++ ){ //checking the rest
for( m = i; m < 15; m++){
if( s_array[Bcount] == array[m] ){
counter++;
i = m;
break;
}
}
}
}
if( j == counter ){
printf( "B is a sub-sequence of A.\n" );
break;
}
else{
printf( "B is not a sub-sequence of A.\n" );
break;
}
}
}
and honestly I can't see if it is the algorithm or that I did something wrong with the coding
First of all the first loop is wrong as i goes up to 15 and at this index you access array out of bounds (undefined behavior).
Then the loop is quite simple. You only need
one loop i index for array and si for s_array
only increment si if you find the number array[i] at s_array[si]
stop the loop if i covered array, or if si got the number of sub array elements (3)
if si is at least 3, the sub sequence was found
That is
int s_array[] = { 5, 7, 13 };
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
int si,i;
for (si=0,i=0 ; i<15 && si<3 ; i++) {
if (s_array[si] == array[i]) si++;
}
printf ("Sub was %s\n", si<3 ? "not found":"found");
Should J not be equal to 3 and the first fot loop index to 14 (or make it strictly less than 15 rather than less than or equal to)? In your second for loop j may be equal to 3 and s_array[3] is invalid. I would try something like:
Bcount = 0;
counter = 1;
for( i = 0; i <= 14; i++ ){
if( s_array[Bcount] == array[i] ){
counter++;
Bcount++;
if(counter == 3){
printf("Success");
break;
}
}
}
In your example, the problem is that the loop get's terminated by the outer if condition:
if( j == counter ){
printf( "B is a sub-sequence of A.\n" );
break;
}
else{
printf( "B is not a sub-sequence of A.\n" );
break;
}
after the first loop cycle, the program checks this condition and breaks.
This condition should be outside the loop.
I am programming in C. What is the best method (I mean in linear time) to spit array on elements less, equals and greater than some value x.
For example if I have array
{1, 4, 6, 7, 13, 1, 7, 3, 5, 11}
and x = 7 then it should be
{1, 4, 6, 1, 3, 5, 7, 7, 13, 11 }
I don't want to sort elements because I need more efficient way. Of course in this example in could be any permutation of {1, 4, 6, 1, 3, 5} and {13, 11}.
My thougt: less or grater than some element in array... In this example it is 7.
My function is:
int x = 7;
int u =0, z = 0;
for(int i=0; i<size-1; i++) // size - 1 because the last element will be choosen value
{
if(A[i] == x)
swap(A[i], A[u]);
else if(A[i] == x)
{
swap(A[i], A[n-(++z)]);
continue;
}
i++
}
for(int i = 0; i<z; i++)
swap(A[u+i],A[size-(++z)];
where u is number of current less elements, and z is the number of equals element
But if I have every elements in array equals there it doesn't work (size-(++z)) is going under 0
This is the so-called Dutch national flag problem, named after the three-striped Dutch flag. (It was named that by E.W. Dijkstra, who was Dutch.) It's similar to the partition function needed to implement quicksort, but in most explanations of quicksort a two-way partitioning algorithm is presented whereas here we are looking for a three-way partition. The classic quicksort partitioning algorithms divide the vector into two parts, one consisting of elements no greater than the pivot and the other consisting of elements strictly greater. [See note 1]
The wikipedia article gives pseudocode for Dijkstra's solution, which (unlike the classic partition algorithm usually presented in discussions of quicksort) moves left to right through the vector:
void dutchflag(int* v, size_t n, int x) {
for (size_t lo = 0, hi = n, j = 0; j < hi; ) {
if (v[j] < x) {
swap(v, lo, j); ++lo; ++j;
} else if (v[j] > x) {
--hi; swap(v, j, hi);
} else {
++j;
}
}
There is another algorithm, discovered in 1993 by Bentley and McIlroy and published in their paper "Engineering a Sort Function" which has some nice diagrams illustrating how various partitioning functions work, as well as some discussion about why partitioning algorithms matter. The Bentley & McIlroy algorithm is better in the case that the pivot element occurs infrequently in the list while Dijkstra's is better if it appears often, so you have to know something about your data in order to choose between them. I believe that most modern quicksort algorithms use Bentley & McIlroy, because the common case is that the array to be sorted has few duplicates.
Notes
The Hoare algorithm as presented in the Wikipedia Quicksort article, does not rearrange values equal to the pivot, so they can end up being present in both partitions. Consequently, it is not a true partitioning algorithm.
You can do this:
1) Loop through the array, if element is less than x then put in new array1.
2)If element is greater than x then put in new array2.
This is linear time O(n)
I tried something like this below which I think is O(n). Took me a little bit to work the kinks out but I think it's pretty similar to the dutchflag answer above.
My ouptput
a.exe
1 4 6 5 3 1 7 7 11 13
1 4 5 6 3 1 7 7 7 11 13
code:
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
void order(int * list, int size, int orderVal)
{
int firstIdx, lastIdx, currVal, tempVal;
firstIdx = 0;
lastIdx = size-1;
for ( ;lastIdx>firstIdx;firstIdx++)
{
currVal = list[firstIdx];
if (currVal >= orderVal)
{
tempVal = list[lastIdx];
list[lastIdx] = currVal;
lastIdx--;
list[firstIdx] = tempVal;
if (tempVal >= orderVal)
firstIdx--;
}
}
lastIdx = size-1;
for( ;lastIdx>firstIdx && middleNum>0;lastIdx--)
{
currVal = list[lastIdx];
if (currVal == orderVal)
{
tempVal = list[firstIdx];
list[firstIdx] = currVal;
firstIdx++;
list[lastIdx] = tempVal;
if (tempVal == orderVal)
lastIdx++;
}
}
}
int main(int argc, char * argv[])
{
int i;
int list[] = {1, 4, 6, 7, 13, 1, 7, 3, 5, 11};
int list2[] = {1, 4, 7, 6, 7, 13, 1, 7, 3, 5, 11};
order(list, ARRAY_SIZE(list), 7);
for (i=0; i<ARRAY_SIZE(list); i++)
printf("%d ", list[i]);
printf("\n");
order(list2, ARRAY_SIZE(list2), 7);
for (i=0; i<ARRAY_SIZE(list2); i++)
printf("%d ", list2[i]);
}
Here is an example using a bubble sort. Which type of sort algorithm is best, is up to you, this is just to demonstrate. Here, I treat values < x as -1, values == x as 0, values > x as 1.
Note that the elements < x and those > x are still in the same sequence.
#include <stdio.h>
int main(void)
{
int array[] = { 1, 4, 6, 7, 13, 1, 7, 3, 5, 11 };
int x = 7;
int len = sizeof array / sizeof array[0];
int i, j, m, n, tmp;
for (i=0; i<len-1; i++) {
m = array[i] < x ? -1 : array[i] == x ? 0 : 1;
for (j=i+1; j<len; j++) {
n = array[j] < x ? -1 : array[j] == x ? 0 : 1;
if (m > n) {
tmp = array[i]; // swap the array element
array[i] = array[j];
array[j] = tmp;
m = n; // and replace alias
}
}
}
for(i=0; i<len; i++)
printf("%d ", array[i]);
printf("\n");
return 0;
}
Program output:
1 4 6 1 3 5 7 7 13 11
int main()
{
static int a[2][2] = {1, 2, 3, 4};
int i, j;
static int *p[] = {(int*)a, (int*)a+1, (int*)a+2};
for(i=0; i<2; i++)
{
for(j=0; j<2; j++)
{
printf("%d, %d, %d, %d\n", *(*(p+i)+j), *(*(j+p)+i),
*(*(i+p)+j), *(*(p+j)+i));
}
}
return 0;
}
When I run this code the output is:
1, 1, 1, 1
2, 2, 2, 2
2, 2, 2, 2
3, 3, 3, 3
Can someone please explain how this code works?
The four pointer operations in the printf:
*(*(p+i)+j)
*(*(j+p)+i)
*(*(i+p)+j)
*(*(p+j)+i)
Evaluate to the following:
*(*(p+i)+j) -> *(p[i]+j)
*(*(j+p)+i) -> *(p[j]+i)
*(*(i+p)+j) -> *(i[p]+j)
*(*(p+j)+i) -> *(j[p]+i)
p[n] is the same as n[p] as the pointer logic (as seen above) is commutitive around +.
see this question for more details.
So there are really only two statements:
*(p[i]+j)
*(p[j]+i)
Of course, this is just p + offset [x] + offset. So really, it is only one statement:
*p[i+j]
Which is of course, the value stored in the p array at offset i+j.
Because of the nested loops, the values of i and j are as follows:
i j i+j
0,0 0
0,1 1
1,0 1
1,1 2
So it prints in turn, the values in each location of p (1,2, 2and3) four times.