Median windows in C - c

I wrote a code to find median filtering (median window). But, I can't make scannig to every number. What can I use instead of size in the for loops. When I use size it ensures just 5 Also, what about boundries ? What can I do for boundries ? Thank you for all appreciated answers. (I've opened new topic because users said that every topic is based on one question.If I did mistake,please delete the question, I will suffix the current question)
<size of array>
<size filter>
<data>
8
3
0 0 0 0 0 0 0 0
0 5 0 0 6 0 0 0
0 0 0 0 0 7 0 0
0 0 0 0 5 0 0 0
0 0 0 5 6 0 0 0
0 0 8 5 5 0 0 0
0 0 0 7 0 0 9 0
0 0 0 0 0 0 0 0
Output:
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 5 5 0 0 0
0 0 0 5 5 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
#include <stdio.h>
int median(int a[100],int n);
int main()
{
int a[100][100];
int temp[100];
int i,j,k,count=0;
int sizefilter;
int sizearray;
scanf("%d", &sizearray);
scanf("%d", &sizefilter);
for(i = 0; i < sizearray; i++)
for(j = 0; j < sizearray; j++)
scanf("%d", &a[i][j]);
for(k = 0; k < sizearray; k++)
for(i = 0; i < sizefilter; i++)
for(j = 0; j < sizefilter; j++)
{
temp[count] = a[i][j];
count++;
a[i][j] = median(temp, count);
}
printf("\n");
printf("\n");
for(i = 0; i < sizearray; i++)
for(j = 0; j < sizearray; j++)
{
printf("%d ", a[i][j]);
if(j == sizearray-1)
printf("\n");
}
return 0;
}
int median(int a[100],int n)
{
int i,j,t;
int result;
/* Sorting begins */
for (i = 1 ; i <= n-1 ; i++)
{ /* Trip-i begins */
for (j = 1 ; j <= n-i ; j++)
{
if (a[j] <= a[j+1])
{ /* Interchanging values */
t = a[j];
a[j] = a[j+1];
a[j+1] = t;
}
else continue ;
}
} /* sorting ends */
/* calculation of median */
if ( n % 2 == 0)
return result = (a[n/2] + a[n/2+1])/2 ;
else
return result = a[n/2 + 1];
}

There are some logical errors in your code:
When you filter, you need four nested loops: The outer two iterate over columns and rows of the matrix, the inner two iterate over columns and rows of the filter area. (That shouldn't be news to you; you have already been told that in an answer to your previous question.)
The constraints of the filter area are simple: The left and top indices must not fall below zero and the right and bottom indicies must be smaller than sizearray. If they are not, adjust them.
You need two arrays, the original array a and a second array that contains the filtered values. You cannot filter in-place, because if you look upwards and to the left, you'll see only filtered values, whereas your filter should always look at the original values.
Your wrong filtering loops apart: You never reset count, which you should reset, of course, for every median value you calculate. You also calculate the median in the inner loop, which is too often. A solution to this is to make count local to the loop that accumulates filter values and determines the median.
Your sorting has index errors. Instead of comparing i with i + 1, compare with ´i - 1. Your indices start from 1, soi - 1` will always yield a valid index.
You buble-sort the array, which is fine for small arrays, but slow in general. The <stdlib.h> has qsort, which may be useful to you for general sorting.
Your median indices are also off by one towards the right.
There are also some stylistic issues:
Please make a habit of using braces for code blocks for for, while and if. Only very trivial code blocks in the innermost scope can be written without braces. In your case, a lot has to be done "between" the loops, and having braces there makes it easy to add stuff.
Yor variable result in median is superfluous. You assign it and then immediately lose the variable itself, because you return. Just returning is enough.
Below is a version of your code that gives the desired output:
#include <stdint.h>
#include <stdio.h>
int min(int a, int b)
{
return a < b ? a : b;
}
int max(int a, int b)
{
return a > b ? a : b;
}
int median(int a[], int n)
{
int i, j;
for (i = 1 ; i < n ; i++) {
for (j = 1 ; j < n ; j++) {
if (a[j] < a[j - 1]) {
int t = a[j];
a[j] = a[j - 1];
a[j - 1] = t;
}
}
}
if (n % 2) return a[n / 2];
return (a[n / 2 - 1] + a[n / 2]) / 2 ;
}
int main()
{
int a[100][100];
int b[100][100];
int temp[100];
int i, j, ii, jj;
int sizefilter;
int sizearray;
scanf("%d", &sizearray);
scanf("%d", &sizefilter);
for(i = 0; i < sizearray; i++) {
for(j = 0; j < sizearray; j++) {
scanf("%d", &a[i][j]);
}
}
for(i = 0; i < sizearray; i++) {
for(j = 0; j < sizearray; j++) {
int imin = max(0, i - sizefilter / 2);
int imax = min(sizearray, i + sizefilter / 2 + 1);
int jmin = max(0, j - sizefilter / 2);
int jmax = min(sizearray, j + sizefilter / 2 + 1);
int count = 0;
for (ii = imin; ii < imax; ii++) {
for (jj = jmin; jj < jmax; jj++) {
temp[count] = a[ii][jj];
count++;
}
}
b[i][j] = median(temp, count);
}
}
for(i = 0; i < sizearray; i++) {
for(j = 0; j < sizearray; j++) {
printf("%3d", b[i][j]);
}
printf("\n");
}
return 0;
}

Related

Shortest path with Bellman & Ford algorithm

I want to implement Shortest path with Bellman & Ford algorithm. my idea is I use adjacent matrix
to save the information of digraph. If I want to find the shorest path of vertex i ,then I observe in-
degree of vertex i by the ith column of adjacent matrix ,and I save the shortest value of ith column
to a variable "min".if I want to find the shorest path from source vertex v to vertex i.
I only compare distance[i] with (distance[j]+ min ), because "min" is equal to adjmatrix[j][i].
In addition, I make the traverse(source, k) function to comfirm which vertex we can reach it in k
steps and use the data structure stack to save information of vertex i. I assume to that i'll get all the
shortest path from source vertex v to every vertex o graph except v itself. But the consequence after
compiling isn't that I expected. I finally got distance[i], 0 <= i < MAX_VERTEX, 1000,-1, 5, 5, 0 ,1000,
1000, respectively. What is my problem? Thanks for answer.
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX 7
#define FALSE 0
#define TRUE 1
#define MAX_DISTANCE_LIMIT 1000
#define MAX_STACK_LENGTH 100
#define MIN(x, y) ((x) < (y) ? x : y)
int stack[MAX_STACK_LENGTH];
int top = -1; //pointer to top of stack.
int adjmatrix[MAX_VERTEX][MAX_VERTEX];
short found[MAX_VERTEX]; //traverse(v ,k) : reach the vertex i By taking the k steps at most
int distance[MAX_VERTEX]; //save the shortest path that source v to every vertex i
int init_matrix(void);
void BellmanFord(int v); //v is source
void traverse(int v,int times);
void push(int vertex);
int pop(void);
int main(void){
int i,j;
init_matrix(); //initial matrix and found[] array
for(i = 0; i < MAX_VERTEX; i++){
for(j = 0; j < MAX_VERTEX; j++)
printf("%2d ", adjmatrix[i][j]);
printf("\n");
}
printf("--------------------------------------------------\n");
BellmanFord(0);
for(i = 0; i < MAX_VERTEX; i++)
printf("%4d ", i);
printf("\n");
for(i = 0; i < MAX_VERTEX; i++)
printf("%4d ", distance[i]);
return 0;
}
int init_matrix(void){
int num_edge = 0, i, j, w;
for(i = 0; i < MAX_VERTEX; i++){
found[i] = FALSE;
for(j = 0; j < MAX_VERTEX; j++)
adjmatrix[i][j] = MAX_DISTANCE_LIMIT; //set a large value to the entry of the vertice which aren't adjacent
}
while(1){
printf("enter the vertices and weight of edge connected between them(w,tail,head): ");
scanf("%d%d%d", &w, &i, &j);
if((i >= MAX_VERTEX) || (j >= MAX_VERTEX)){
fprintf(stderr, "index if the matrix should be less than %d");
exit(EXIT_FAILURE);
}
if(w == 0) break;
adjmatrix[i][j] = w;
num_edge++;
}
return num_edge;
}
void BellmanFord(int v){//compute all shortest path from v to every vertex ,and allow edge is negative
int i, k, min = MAX_DISTANCE_LIMIT, j, minpos;
for(int i = 0; i < MAX_VERTEX; i++)
distance[i] = adjmatrix[v][i]; //value of dist"1"
for(k = 2; k <= MAX_VERTEX - 1; k++){
traverse(v,k); //traverse(v ,k)will set found[i] that we can reach in k steps TRUE.
for(i = 0; i < MAX_VERTEX; i++ ){
if( found[i] == FALSE)
continue;
for(j = 0; j < MAX_VERTEX; j++)
if(adjmatrix[j][i]+distance[j] < min) {
min = adjmatrix[j][i]+distance[j];
minpos = j;
}
distance[i] = MIN(distance[i],adjmatrix[minpos][i]+distance[j]);
}
for(i = 0; i < MAX_VERTEX; i++ ) //initial found array to FALSE
found[i] = FALSE;
}
}
void traverse(int v,int times){
int i, next_order ,count = 0;
if (times == 0) return ;
for(i = 0; i < MAX_VERTEX; i++){
if((adjmatrix[v][i] != MAX_DISTANCE_LIMIT) && (!found[i])){
found[i] = TRUE;
if(times == 1)
return;
push(i);
count++;
}
}
for(i = 0; i < count; i++){
next_order = pop();
traverse(next_order,times-1);
}
return;
}
void push(int vertex){
if(top >= MAX_STACK_LENGTH){
fprintf(stderr, "The stack is full.");
exit(EXIT_FAILURE);
}
stack[++top] = vertex;
}
int pop(void){
if(top == -1){
fprintf(stderr, "The stack is empty.\n");
exit(EXIT_FAILURE);
}
else
return stack[top--];
}
/************************************
*graph information (w,tail,head)
input
6 0 1
5 0 2
5 0 3
-1 1 4
1 2 4
-2 2 1
-2 3 2
-1 3 5
3 5 6
3 4 6
0 0 0 //end the input
************************************
adjmatrix:
0 6 5 5 0 0 0
0 0 0 0 -1 0 0
0 -2 0 0 1 0 0
0 0 -2 0 0 -1 0
0 0 0 0 0 0 3
0 0 0 0 0 0 3
0 0 0 0 0 0 0
**************************************/

Function. 2 2D arrays, the second is full of 0's, after applying condition,copy the whole row from first 2D array to the second 2D array

So, for example I have 2 Arrays, one is
0 -1 1 0 1
0 -1 0 0 0
0 1 1 -1 0
0 0 0 -1 0
0 -1 0 1 0
the second is full of 0's.
After I meet the condition a[i][j] == -1 && a[i][k] == 1, where k=j+1, I need to copy the whole row and put it into the second array, so the result should be:
0 -1 1 0 1
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 -1 0 1 0
I've already alloced the memory for both arrays, and here's the part of the code that I've tried but it doesnt work, it copies the whole array
void copy_row(int **a, int **b, int m){
for(int i=0; i<m; i++){
b[i]=a[i];
}
}
int main(){
...
for(int i=0 ; i<n ; i++){
for(int j=0 ; j<m ; j++){
for(int k=j+1; k<m ; k++){
if (a[i][j]==-1 && a[i][k]==1){
copy_row(a,b,n);
}
}
}
}
If you want to copy a row, you would need to pass the index of the current row to copy_row, plus the number of columns.
The call from main could be
// Notice that we pass index i and not n
copy_row(m, a, b, i);
The copy_row could be:
void copy_row(int numOfColumns, int a[][numOfColumns], int b[][numOfColumns], int rowIndex) {
for (int ii = 0, ii < numOfColumns, ++ii) {
b[rowIndex][ii] = a[rowIndex][ii];
}
}
You could add a break after the call to copy_row in the if statement. Once a row is copied, there is no need to keep checking the rest of the columns for -1.
E.g., you might reduce the checks made by using
for(int j = 0 ; j < m ; ++j) {
if (a[i][j] == -1) {
for(int k = j + 1; k < m ; ++k) {
if (a[i][k] == 1) {
copy_row(m, a, b, i);
break;
}
}
break;
}
}

check column and row in sodoku- C programming

I'm trying to check if number (from 1 to n)
appears more than once in
row or column in sodoku board
I wrote a code that goes over each row and column and checks the numbers between 1 to n (every time checking number at a time after finishing with row 0 (for example) goes to the next one (if it wasn't true in the row before)
my code is working just if there is a number
appearing more than once
in row 0 (if there is in other rows it returns nothing!)
and for the column it doesn't return any thing
this is a matrix that I use for the test (matrix with solution and I change numbers in rows or columns):
7 1 0 0 0 0 6 0 9
2 0 0 0 0 3 0 0 0
0 0 0 1 5 0 0 0 8
0 0 7 0 0 0 0 9 0
0 0 6 0 0 0 7 0 0
0 2 0 0 0 0 4 0 0
1 0 0 0 2 9 0 0 0
0 0 0 3 0 0 0 0 4
9 0 5 0 0 0 0 8 6
and this is my code:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX4USED 10
int n; //size of the sodoku board
bool CheckAppearingInRow(int matrix [n][n]) {
int used[MAX4USED] = {0};
int index = 1;
int row = 0;
while (index <= n) {
for(int j = 0; j < n; j++) {
if(matrix[row][j] == index ) {
used[index] +=1;
}
}
for(int i = 0; i <= n ; i++) {
if (used[i] > 1) {
return true;
}
used[i] = 0;
}
index += 1;
}
row += 1;
while (row < n) {
CheckAppearingInRow(matrix);
}
return false;
}
bool CheckAppearingInColumn(int matrix [n][n]) {
int used[MAX4USED] = {0};
int index = 1;
int col = 0;
while (index <= n) {
for(int i = 0; i < n; i++) {
if(matrix[i][col] == index ) {
used[index] +=1;
}
}
for(int i = 0; i <= n ; i++) {
if (used[i] > 1) {
return true;
}
used[i] = 0;
}
index += 1;
}
col += 1;
while(col < n){
CheckAppearingInColumn(matrix);
}
return false;
}
int main() {
printf("Please enter your sodoku dimension:");
scanf("%d", &n);
int a[n][n];
printf("\nInsert your sodoku board\n");
printf("Instruction: Enter 0 for blank\n");
for(int i=0; i<n; i++){
for(int j=0; j<n; j++) {
scanf("%d", &a[i][j]);
}
}
if (CheckAppearingInRow(a)== true || CheckAppearingInColumn(a) == true) {
printf("\nNo solution!\n");
}
return 0;
}

Moving elements in 2d array

I have 2d array filled with random numbers.
For example:
#define d 4
int main(void)
{
int a[d][d];
int primary[d], secondary[d];
size_t i, j;
srand(time(NULL)); /* fill array with random numbers */
for (i = 0; i < d; i++)
{for (j = 0; j < d; j++)
a[i][j] = rand() % 100;
}
How to change diagonals . For example :
1 0 0 0 2 2 0 0 0 1
0 3 0 4 0 0 4 0 3 0
0 0 5 0 0 to 0 0 5 0 0
0 6 0 7 0 0 7 0 6 0
8 0 0 0 9 9 0 0 0 8
Task is to print random matrix of d size then change diagonals placement using cycle and print it again.However i`m not getting how cycle should look like.
Appreciate any hints or examples.
Loop while j < d / 2 and then swap the values:
for (i = 0; i < d; i++) {
for (j = 0; j < d / 2; j++) {
int temp = a[i][j];
a[i][j] = a[i][d - j -1];
a[i][d - j -1] = temp;
}
}

How to read nested for-loops?

I cannot understand what this for-loop does by reading the code. I know how a for-loop works though. By reading this code I literally gain no insight into what the program could be doing.
I'm coming from python to C, if that matters.
#include <stdio.h>
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];
return 0;
}
for (j = 0; j < 10; ++j)
This just means iterate through each element of the array. It is easy to understand.
for (i = 0; i < j; ++i)
numbers[j] += numbers[i];
This is much harder! I think it is because I cannot figure out in my head what j would be equal to. I cannot follow the two loops properly.
I would specifically like to know how I can read and understand this nested for-loop in C.
(I know what this snippet does because I compiled and ran the code.)
First of all, let's translate it into Python:
numbers = [1,0,0,0,0,0,0,0,0,0]
for j in range(10):
for i in range(j):
numbers[j] += numbers[i]
The outer loop iterates through all ten elements of numbers and, for each item, adds all previous elements in numbers to the current one. It's easier to follow if you add a few print statements.
for (j = 0; j < 10; ++j) doesn't mean "iterate through each element of the array". It means "for each value of j from 0 to 9, execute the code within the loop".
The code within the loop includes another loop:
for (i = 0; i < j; ++i)
numbers[j] += numbers[i];
So, for each value of j from 0 to 9, that inner loop will be executed. In effect, it would be like executing the inner loop sequentially 10 times:
for (i = 0; i < 0; ++i)
numbers[0] += numbers[i];
for (i = 0; i < 1; ++i)
numbers[1] += numbers[i];
for (i = 0; i < 2; ++i)
numbers[2] += numbers[i];
... and so on
(As a side note, the first execution of the inner loop does nothing, since 0 is not less than 0. So the initial value of the outer loop might as well be 1.)
To return to your original phrasing, if the outer loop essentially iterates over all elements of the array, the inner loop does a second iteration over all elements of the array prior to the current element in the outer loop.
Some times it is helpful to just write out what is happening along the way. Also, adding braces might help a little bit as well:
for (j = 0; j < 10; ++j)
{
for (i = 0; i < j; ++i)
{
numbers[j] += numbers[i];
}
}
(A) The first time through the outer loop, j will be zero, thus the inner loop will read:
for (i=0; i < 0; ++i)
because 0 is not less than 0, we skip the body of the inner loop (and numbers remains unchanged).
(B) The second time through the outer loop, j will be one, thus the inner loop will read:
for (i=0; i < 1; ++i)
So we will go through the body of the inner-loop once with i being zero, thus we will execute this
command; numbers[1] = numbers[1] + numbers[0]; (I expanded += for added clarity) which will now make the numbers array look like this: 1,1,0,0,0,0,0,0,0,0
(C) The third time through the outer loop, j will be two, thus the inner loop will read:
for(i=0; i < 2; ++i)
SO we will go through the body of the inner-loop twice with i being first zero, and then one. Thus
we will execute the following commands:
numbers[2] = numbers[2] + numbers[0];
numbers[2] = numbers[2] + numbers[1];
which will transform the numbers array into 1,1,2,0,0,0,0,0,0,0
and so on.
Hope this helps.
The jth element in the numbers array is the sum of all preceding elements in the array. Technically, the preceding elements gets added to the jth element, but numbers[j] is 0 to begin with.
When j equals 1,
numbers[1] = numbers[1] + numbers[0]
which makes numbers[1] == 1. (because i can only be 0 and numbers[0] is 1)
When j equals 2,
numbers[2] = numbers[2] + numbers[1] + numbers[0]
which makes numbers[2] == 2. (because i can be 0 and 1, and numbers[0] and numbers[1] are both 1)
When j equals 3,
numbers[3] = numbers[3] + numbers[2] + numbers[1] + numbers[0]
which makes numbers[3] == 4. (because i can be 0, 1 and 2, and numbers[2] is 2)
As such, any j - 1th (j > 1) element equals the sum of all of its preceding elements. Hence, as the loop goes on, the jth element would end up becoming the double of the j - 1th element.
At the end of the program, each value in the array would be 1 1 2 4 8 16 32 64 128 256
here is the value of your array after each outer loop
1 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0
1 1 2 0 0 0 0 0 0 0
1 1 2 4 0 0 0 0 0 0
1 1 2 4 8 0 0 0 0 0
1 1 2 4 8 16 0 0 0 0
1 1 2 4 8 16 32 0 0 0
1 1 2 4 8 16 32 64 0 0
1 1 2 4 8 16 32 64 128 0
1 1 2 4 8 16 32 64 128 256
as generated by this
#include <stdio.h>
#define SIZE_ARRAY 10
void show_numbers(int size_array, int index, int given_array[]) {
int i = 0;
for (; i < size_array; i++) {
printf("%3d ", given_array[i]);
}
printf("\n");
}
int main (void) {
// static const int size_array = 10;
int numbers[SIZE_ARRAY] = {1,0,0,0,0,0,0,0,0,0};
int i, j;
show_numbers(SIZE_ARRAY, 0, numbers);
for (j = 0; j < SIZE_ARRAY; ++j) {
for (i = 0; i < j; ++i) {
numbers[j] += numbers[i];
}
show_numbers(SIZE_ARRAY, j, numbers);
}
return 0;
}

Resources