Looping through an array to check a condition - c

I'm using a FOR loop to loop through an array to check a condition but it seems to duplicate the variables I want to print.
Here's my code:
/*Printing the matrix*/
for(row=0;row<15;row++)
{
for(col=0;col<8;col++)
{
for(a=0;a<sizeof(row_sel)/(sizeof(row_sel[0]));a++)
{
if(row==row_sel[a] && col==col_sel[a])
{
printf("|%d|",matrix[row][col]);
}
else
{
printf(" %d ",matrix[row][col]);
}
}
}
printf("\n");
}
What I'm trying to print is:
|0| 6 7 3 6 6 9 5
0 0 0 0 0 0 0 0
2 8 8 4 8 4 0 0
0 0 0 0 0 0 0 0
5 0 8 7 9 5 5 3
0 0 0 0 0 0 0 0
2 7 8 5 3 3 8 6
0 0 0 0 0 0 0 0
6 6 4 2 9 6 2 1
0 0 0 0 0 0 0 0
9 4 0 6 6 7 0 4
0 0 0 0 0 0 0 0
4 3 8 9 0 2 2 7
0 0 0 0 0 0 0 0
0 3 6 7 8 3 5 |2|
But instead I get this output, I don't know why the values are duplicated,the loop should've ended or skipped the statement:
|0| 0 0 1 1 1 2 2 2 7 7 7 7 7 7 3 3 3 6 6 6 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 0 0
0 0 0 6 6 6 3 3 3 2 2 2 0 0 0 4 4 4 2 2 2 9 9 9
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
5 5 5 4 4 4 6 6 6 3 3 3 5 5 5 8 8 8 6 6 6 5 5 5
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
5 5 5 7 7 7 1 1 1 9 9 9 1 1 1 2 2 2 0 0 0 4 4 4
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
9 9 9 7 7 7 3 3 3 6 6 6 8 8 8 0 0 0 3 3 3 8 8 8
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
5 5 5 2 2 2 6 6 6 5 5 5 2 2 2 7 7 7 5 5 5 5 5 5
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
5 5 5 7 7 7 8 8 8 3 3 3 2 2 2 1 1 1 1 1 1 6 6 6
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
9 9 9 6 6 6 9 9 9 7 7 7 2 2 2 6 6 6 2 2 2 5 |5| 5
Any tips to where I went wrong? Any help is quite appreciated.

Your problem:
You print each value of the matrix for every a, but you only want to print it once.
The solution:
You have to move the if-else statement out of the innermost loop:
for(row=0;row<15;row++)
{
for(col=0;col<8;col++)
{
bool foundMatch = false;
for(a=0;!foundMatch && a<sizeof(row_sel)/(sizeof(row_sel[0]));a++)
{
foundMatch = row==row_sel[a] && col==col_sel[a];
}
if(foundMatch)
{
printf("|%d|",matrix[row][col]);
}
else
{
printf(" %d ",matrix[row][col]);
}
}
printf("\n");
}
Why/How it works:
The inner loop will run until foundMatch is true, or a gets out of range.
foundMatch is set to true if there is any a for which row==row_sel[a] && col==col_sel[a] is true.
|%d| will print if foundMatch is true.

Related

How to do padding for a matrix

I am trying to do the padding for a basic matrix.
For example, I have a 3 * 3 matrix and I want to pad it to 7 * 7 matrix:
3x3 Matrix
1 2 3
4 5 6
7 8 9
Is there any efficient way to add 2 padding to on the matrix?
7x7 Matrix After Padding
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 1 2 3 0 0
0 0 4 5 6 0 0
0 0 7 8 9 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0

How to find elements in an array based on a search from another array

Imagine that i have two arrays:
a = [1 1 1 1 5 5 5 5 5 5 8 8;
1 1 1 3 5 5 5 5 5 8 8 8;
1 1 3 3 3 5 5 5 8 8 8 8;
1 3 3 3 3 3 5 8 8 8 8 8;
4 4 4 9 9 0 3 3 8 8 8 8;
4 4 4 9 0 0 3 3 3 3 8 8;
4 4 9 9 0 0 0 0 0 0 1 1;
4 9 9 9 0 0 0 0 0 0 1 1;
9 9 9 9 9 0 0 0 7 7 7 7];
b = [4 5 7];
I want ans like this :
ans =
0 0 0 0 1 1 1 1 1 1 0 0
0 0 0 0 1 1 1 1 1 0 0 0
0 0 0 0 0 1 1 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0
1 1 1 0 0 0 0 0 0 0 0 0
1 1 1 0 0 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 1 1
The function ismember does exactly that:
ismember(a, b)
ans =
9×12 logical array
0 0 0 0 1 1 1 1 1 1 0 0
0 0 0 0 1 1 1 1 1 0 0 0
0 0 0 0 0 1 1 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0
1 1 1 0 0 0 0 0 0 0 0 0
1 1 1 0 0 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 1 1
Not sure if this is the most efficient but this should work:
c = zeros(size(a));
for i = 1:numel(a)
if ismember(a(i), b(:))
c(i) = 1
end
end
Testing on some smaller arrays:
octave:1> a = [1 1 5 5 8 8;1 5 1 3 5 8]
a =
1 1 5 5 8 8
1 5 1 3 5 8
octave:2> b = [5 8]
b =
5 8
octave:3> c = zeros(size(a));
for i = 1:numel(a)
if ismember(a(i), b(:))
c(i) = 1
end
end
c =
0 0 0 0 0 0
0 1 0 0 0 0
.
.
.
c =
0 0 1 1 1 1
0 1 0 0 1 0
c =
0 0 1 1 1 1
0 1 0 0 1 1

How can I build a decreasing lower triangular matrix? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Do you know if it is possible to get the following triangular matrix
[ N:-1:1; (N-1):-1:0; (N-2):-1:0 0; (N-3):-1:0 0 0; ....] without writing every line with horzcat and without using a loop?
thanks all
Fred
Is this what you want?
N = 8;
result = flipud(tril(toeplitz(1:N)));
This gives
result =
8 7 6 5 4 3 2 1
7 6 5 4 3 2 1 0
6 5 4 3 2 1 0 0
5 4 3 2 1 0 0 0
4 3 2 1 0 0 0 0
3 2 1 0 0 0 0 0
2 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
Maybe something like this:
N=10;
M=triu(gallery('circul',N)).'
M =
1 0 0 0 0 0 0 0 0 0
2 1 0 0 0 0 0 0 0 0
3 2 1 0 0 0 0 0 0 0
4 3 2 1 0 0 0 0 0 0
5 4 3 2 1 0 0 0 0 0
6 5 4 3 2 1 0 0 0 0
7 6 5 4 3 2 1 0 0 0
8 7 6 5 4 3 2 1 0 0
9 8 7 6 5 4 3 2 1 0
10 9 8 7 6 5 4 3 2 1
Or did you want this:
M=fliplr(triu(gallery('circul',N)))
M =
10 9 8 7 6 5 4 3 2 1
9 8 7 6 5 4 3 2 1 0
8 7 6 5 4 3 2 1 0 0
7 6 5 4 3 2 1 0 0 0
6 5 4 3 2 1 0 0 0 0
5 4 3 2 1 0 0 0 0 0
4 3 2 1 0 0 0 0 0 0
3 2 1 0 0 0 0 0 0 0
2 1 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
I couldn't really tell from your code sample which direction you wanted this to go.
The power of bsxfun compels you!
[[N:-1:1]' reshape(repmat([N-1:-1:1]',1,N).*bsxfun(#ge,[1:N-1]',1:N),N,[])]
Sample run -
>> N = 8;
>> [[N:-1:1]' reshape(repmat([N-1:-1:1]',1,N).*bsxfun(#ge,[1:N-1]',1:N),N,[])]
ans =
8 7 6 5 4 3 2 1
7 6 5 4 3 2 1 0
6 5 4 3 2 1 0 0
5 4 3 2 1 0 0 0
4 3 2 1 0 0 0 0
3 2 1 0 0 0 0 0
2 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
This is basically inspired by this another bsxfun-based solution to a very similar question - Replicate vector and shift each copy by 1 row down without for-loop. There you can see similar solutions and related benchmarks, as it seems performance is a concern here.

How to detect connected components in a 2D array?

As mentioned the title above. I want to find out whether there are how many components in a 2D Array. Whereas, components are made by 1 numbers and there are only 0 and 1 number in the array.
I implemented this problem by using DFS (Deep First Search) algorithm with recursive calls and an array to mark cell visited.
However, I want to implement this problem with another way without using recursion, stack, queue, struct... Only using for/while function are allowed.
Example:
Array data:
0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1
0 0 1 1 1 0 1 1 0 1 0 0 0 0 0 1
0 0 1 0 1 0 1 1 0 1 0 1 1 1 0 1
0 0 1 0 1 0 0 0 0 1 0 1 0 1 0 1
0 0 1 0 1 0 0 0 0 1 0 1 0 1 0 1
0 0 1 1 1 0 0 0 0 1 0 1 0 1 0 1
0 0 0 0 0 1 1 1 0 1 0 1 1 1 0 1
0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 1
0 0 0 0 0 1 1 1 0 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 1 1 1 1 0 0 0 0 1 1 1 1 0 0
0 1 0 0 0 1 0 0 0 0 1 0 0 1 0 0
0 1 0 1 1 1 1 1 0 0 1 1 1 1 0 0
0 1 0 1 0 1 0 1 0 0 1 1 1 1 0 0
0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
Array after determined components with specific labels.
0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1
0 0 2 2 2 0 3 3 0 1 0 0 0 0 0 1
0 0 2 0 2 0 3 3 0 1 0 4 4 4 0 1
0 0 2 0 2 0 0 0 0 1 0 4 0 4 0 1
0 0 2 0 2 0 0 0 0 1 0 4 0 4 0 1
0 0 2 2 2 0 0 0 0 1 0 4 0 4 0 1
0 0 0 0 0 5 5 5 0 1 0 4 4 4 0 1
0 0 0 0 0 5 0 5 0 1 0 0 0 0 0 1
0 0 0 0 0 5 5 5 0 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 6 6 6 6 6 0 0 0 0 7 7 7 7 0 0
0 6 0 0 0 6 0 0 0 0 7 0 0 7 0 0
0 6 0 6 6 6 6 6 0 0 7 7 7 7 0 0
0 6 0 6 0 6 0 6 0 0 7 7 7 7 0 0
0 6 6 6 6 6 6 6 0 0 0 0 0 0 0 0
0 6 6 6 6 6 6 6 0 0 0 0 0 0 0 0
Thank you in advance.
I guess you could iterate through the matrix, and check the neighbours for each cell, and copy the value of the neighbour if that is > 0 or set a new value if all the neighbours are 0. In pseudocode:
comp = 1
for i = 0 to n:
for j = 0 to n:
for nei : neighbours(i, j):
if nei > 0:
m[i,j] = nei
break
m[i,j] = comp
comp++
And neighbours are the 4 (or 2) adjacent neighbouring cells to (i, j)

Data frame column value with range condition [duplicate]

This question already has answers here:
R add new column with predefined pattern
(2 answers)
Closed 8 years ago.
I want to create the columns below wherein I can specify the range to apply the value 1 to one column and the rest 0. I know this has been asked and answered perfectly here before but I can't find that particular one right now.
time1 time2 time3 time4 time5
1 1 0 0 0 0
2 1 0 0 0 0
3 1 0 0 0 0
4 1 0 0 0 0
5 1 0 0 0 0
6 0 1 0 0 0
7 0 1 0 0 0
8 0 1 0 0 0
9 0 1 0 0 0
10 0 1 0 0 0
11 0 0 1 0 0
12 0 0 1 0 0
13 0 0 1 0 0
14 0 0 1 0 0
15 0 0 1 0 0
16 0 0 0 1 0
17 0 0 0 1 0
18 0 0 0 1 0
19 0 0 0 1 0
20 0 0 0 1 0
21 0 0 0 0 1
22 0 0 0 0 1
23 0 0 0 0 1
24 0 0 0 0 1
25 0 0 0 0 1
I can't recall how this was generated but the answer included an n option to specify the intervals per column.
You could do
cols <- 4
diag(cols)[rep(1:cols, each=cols), ]
[,1] [,2] [,3] [,4]
[1,] 1 0 0 0
[2,] 1 0 0 0
[3,] 1 0 0 0
[4,] 1 0 0 0
[5,] 0 1 0 0
[6,] 0 1 0 0
[7,] 0 1 0 0
[8,] 0 1 0 0
[9,] 0 0 1 0
[10,] 0 0 1 0
[11,] 0 0 1 0
[12,] 0 0 1 0
[13,] 0 0 0 1
[14,] 0 0 0 1
[15,] 0 0 0 1
[16,] 0 0 0 1
I finally found the exact question: "R add new column with predefined pattern" and the solution I was looking for is:
range <- 5
cols <- 5
y <- gl(cols, range)
mat <- model.matrix(~y-1) # -1 is for remove the intercept
colnames(mat) <- paste0('var', 1:cols)
mat
It provides a dataframe ready to be included in other dataframes (via merge(old, new)) and specifying a name for the columns.
The output is:
var1 var2 var3 var4 var5
1 1 0 0 0 0
2 1 0 0 0 0
3 1 0 0 0 0
4 1 0 0 0 0
5 1 0 0 0 0
6 0 1 0 0 0
7 0 1 0 0 0
8 0 1 0 0 0
9 0 1 0 0 0
10 0 1 0 0 0
11 0 0 1 0 0
12 0 0 1 0 0
13 0 0 1 0 0
14 0 0 1 0 0
15 0 0 1 0 0
16 0 0 0 1 0
17 0 0 0 1 0
18 0 0 0 1 0
19 0 0 0 1 0
20 0 0 0 1 0
21 0 0 0 0 1
22 0 0 0 0 1
23 0 0 0 0 1
24 0 0 0 0 1
25 0 0 0 0 1

Resources