DFS Adjacency matrix - c

I'm trying to make a directed DFS traversal path from an adjacency matrix. Basically print out the path in nodes, but the output is always bad for some reason. Even though the code looks sound, it never actually follows the path.
#include <stdio.h>
#include <stdlib.h>
#define MAX 10
void DFS(int i, int graph[][MAX], int n, int visited[MAX] );
void visit_all(int graph[][MAX], int n);
void read_matrix(int graph [][MAX], int n);
int main() {
int graph[MAX][MAX];
int n;
printf("Input matrix dimension: ");
scanf("%d", &n);
if (n>MAX) {
fprintf(stderr, "Too large\n");
exit(1);
}
read_matrix(graph, n);
visit_all(graph, n);
return 0;
}
void DFS(int v, int graph[][MAX], int n, int visited[MAX]) {
int w;
printf("%d ", v);
visited[v] = 1;
for(w=0;w<n;w++)
if (visited[w] == 0 && graph[v][w] == 1)
DFS(w, graph, n, visited);
}
void visit_all(int graph[][MAX], int n) {
int v, visited[MAX];
for(v=0;v<n;v++)
visited[v] = 0;
for(v=0;v<n;v++)
if (visited[v] == 0)
DFS(v, graph, n, visited);
printf("\n");
}
void read_matrix(int graph [][MAX], int n) {
int i, j;
for(i=0;i<n;i++)
for (j=0;j<n;j++)
graph[i][j] = 0;
printf("\Input elements in format [ij], CTRL+D to end\n");
while(scanf("%d%d", &i, &j) != EOF) {
graph[i][j] = 1;
}
}

Input elements in format [ij]
Scanf of 57 using %d%d will not give you 5,7 – stark

Related

Error in User defined size for array in c

*I am taking the size of array from user, the program runs perfectly when i declare int arr[n]; below the scanf in main but, it when i run following code is behaves differently each time, sometimes take more values, some times shows bus error. Even the value of n changes sometimes. *
//Code
#include <stdio.h>
void read_array(int arr[], int *n);
void print_array(int arr[], int *n);
int main() {
int n;
int arr[] = {};
printf("Enter array length ");
scanf("%d", &n);
printf("\nmain elements %d", n);
read_array(arr, &n);
printf("\nElements main %d", n);
print_array(arr, &n);
return 0;
}
void read_array(int arr[], int *n) {
int i;
printf("\n Elements R_A %d", *n);
printf("\nEnter elements");
for (i = 0; i < *n; i++) scanf("%d", &arr[i]);
}
void print_array(int arr[], int *n) {
int i;
printf("\n");
for (i = 0; i < *n; i++) printf("%d ", arr[i]);
printf("\n Elements P_A %d", *n);
}
When an array is declared without an explicit size, it size is taken to be the number of elements it is initialized with. So This:
int arr[]={};
Declares an array of size 0 which is invalid, and attempting to use it triggers undefined behavior.
int arr[] = {}; is a zero-length array (not supported by the standard) and you access it out of bounds.
If your compiler supports VLAs (variable length arrays), you could use one of those instead.
Example:
#include <stdio.h>
void read_array(int arr[], int *n);
void print_array(int arr[], int n); // no need to send in a pointer to n
int main() {
int n;
printf("Enter array length ");
if (scanf("%d", &n) != 1 || n < 1) return 1; // check that scanf succeeded
printf("\nmain elements %d", n);
int arr[n]; // a VLA of n elements
read_array(arr, &n);
printf("\nElements main %d", n);
print_array(arr, n);
return 0;
}
void read_array(int arr[], int *n) {
printf("\n Elements R_A %d", *n);
printf("\nEnter elements");
int i;
for (i = 0; i < *n; i++) {
if (scanf("%d", &arr[i]) != 1) break; // check that scanf succeeded
}
*n = i; // store the number of elements successfully read
}
void print_array(int arr[], int n) {
int i;
printf("\n");
for (i = 0; i < n; i++) printf("%d ", arr[i]);
printf("\n Elements P_A %d", n);
}

min heap program stopped working

I am doing a simple minheap program but when size of heap is 4 i get an error program stopped working.
i checked heap size 2,3,5,6,7 program is working fine.
Why am i getting this error only when heapsize is 4?
I am using codeblocks 16.01, windows 10, gcc compiler.
minHeap.c
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
void MinHeapfy(int A[], int i, int N)
{
int l,r,temp,smallest;
l = 2*i;
r = 2*i + 1;
if((l<=N) && (A[l]<A[i]))
{
smallest = l;
}
else
{
smallest = i;
}
if((r<=N) && (A[r]<A[smallest]))
{
smallest = r;
}
if(smallest != i)
{
temp = A[smallest];
A[smallest] = A[i];
A[i] = temp;
MinHeapfy(A,smallest,N);
}
}
void BuildHeap(int A[],int N)
{
int i;
int f = floor(N/2);
printf("f %d", f);
for(i=f;i>=1;i--)
{
printf("i %d\n",i);
MinHeapfy(A,i,N);
}
}
int main()
{
int *A,N,T,data,q,i=1;
scanf("%d",&N);
A = (int *)calloc(N,sizeof(int));
for(i=1;i<=N;i++)
{
scanf("%d",&data);
A[i]=data;
}
BuildHeap(A,N);
for(i=1;i<=N;i++)
{
printf("%d ",A[i]);
}
return 0;
}
I can share some things that I learned till now:
void BuildHeap(int *A, int N);
void MinHeapfy(int *A, int i, int N);
In this 2 functions you just send a pointer not an array(difference between int *A and int A[5])
int main()
{
/*here it is better for you to declare like this
to see more easier which is which pointer and variable
(PS: at the moment you don't use q)*/
int N,T,data,i;//,q
int *A;
scanf("%d",&N);
A = (int *)calloc(N,sizeof(int));
for(i=0;i<N;i++)
{
scanf("%d",&data);
A[i]=data;
}
BuildHeap(A,N);
for(i=0;i<N;i++)
{
printf("%d ",A[i]);
}
return 0;
}
The 2 fors that you use must start from 0 to N
When you write:
A[0] <=> address pointed by A + 0 * sizeof(data type of A)
So 0 is the first address of the array
and the last address is N-1
A[N-1] <=> address pointed by A + (N-1) * sizeof(data type of A)

How to update values of an array in C

Here's my problem :
I have a program where the user have to fill this :
a 2d array of a list of elements from which i can at most take one element ( we'll call it exclusionArr )
a 2d array of a list of elements from which i have to at least take one element ( we'll call it inclusionArr )
an array with the elements i have to keep ( we'll call it keepArr )
an array with the elements i can't use ( we'll call it throwArr )
Now on the first step i need to check if any row of exclusionArr contain an element of keepArr and if it does then i need to add every element of that row but that one in throwArr.
One row cannot contain more than one element of keepArr, i'll make a function to check for that and return an error if it is. ( you can at most keep one item from the rows of exclusionArr so having 2 elements of keepArr on the same row is a problem )
I need help to add element to an array, i can't seem to be able to store those values in my array (more like i don't really know how to, still new to C).
Here's the function i made so far :
void interdiction(int *throwArr[], int *throw_size, int keepArr[], int keep_size, int x, int y, int exceptionArr[x][y]) {
int i, j, k, count=0;
while(count<keep_size) {
for(i=0;i<x;i++) {
for(j=0;j<y;j++) {
if (exceptionArr[i][j] == keepArr[count]) {
for (k=0;k<y;k++) {
if(k!=j) {
printf("\nElement %d of exclusion %d inserted in throwArr",exceptionArr[i][k], i);
*throw_size+=1;
throwArr[*throw_size]=exceptionArr[i][k];
}
else printf("\nelement to keep found in exclusion %d in position %d", i, j);
}
}
}
}
count++;
}
}
I would like it to change the throwArr that i put in the function so that it adds on the already existing array every element on the current row except the element that's in keepArr.
I don't know if it's relevant or not but for throwArr when initializing it i allocate a lot of extra memory so i could perform changes without running out of space so i don't know if i need to realloc memory in the function for the changes done.
Any help would be greatly appreciated !
EDIT : Here's the full code
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
void interdiction(int *throwArr, int throw_size, int *keepArr, int keep_size, int x, int y, int exclusionArr[x][y]);
static int compare (void const *a, void const *b);
void noDuplicate( int arr[], int *size );
void xclusion_alloc (int x, int y, int(**aptr)[x][y]);
void xclusion_print (int x, int y, int array[x][y]);
void xclusion_fill (int x, int y, int array[x][y]);
void main(){
int throw_size, keep_size, rexc, lexc;
int i, j;
int nbObjets=7, *throwArr, *keepArr, (*exclusionArr)[rexc][lexc];
printf("\nHow many exclusions :");
scanf("%d", &rexc);
printf("\nHow many elements in each exclusion :");
scanf("%d", &lexc);
xclusion_alloc(rexc,lexc,&exclusionArr);
xclusion_fill(rexc,lexc,*exclusionArr);
xclusion_print(rexc,lexc,*exclusionArr);
printf("\nHow many elements do we have to keep :");
scanf("%d", &keep_size);
keepArr=malloc(nbObjets*sizeof(int));
printf("\nWhat are they :");
for(i=0;i<keep_size;i++){
scanf("%d",&keepArr[i]);
}
qsort(keepArr, keep_size, sizeof *keepArr, compare);
noDuplicate(keepArr, &keep_size);
printf("\nHow many elements we can't use :");
scanf("%d", &throw_size);
throwArr=malloc(nbObjets*sizeof(int));
printf("\nWhat are they :");
for(i=0;i<throw_size;i++){
scanf("%d",&throwArr[i]);
}
qsort(throwArr, throw_size, sizeof *throwArr, compare);
noDuplicate(throwArr, &throw_size);
interdiction(throwArr, throw_size, keepArr, keep_size, rexc, lexc, *exclusionArr);
printf("\nOur array of elements we can't use : ");
for (i=0;i<throw_size;i++){
printf("%d ", throwArr[i]);
}
}
static int compare (void const *a, void const *b){
int const *pa = a;
int const *pb = b;
return *pa - *pb;
}
void interdiction(int *throwArr, int throw_size, int *keepArr, int keep_size, int x, int y, int exclusionArr[x][y]){
int i, j, k, count=0;
while(count<keep_size){
for(i=0;i<x;i++) {
for(j=0;j<y;j++) {
if (exclusionArr[i][j] == keepArr[count]) {
for (k=0;k<y;k++){
if(k!=j){
printf("\nElement %d of exclusion %d inserted in the array of elements we can't use",exclusionArr[i][k], i);
throw_size+=1;
throwArr[throw_size]=exclusionArr[i][k];
}
else printf("\nelement to keep found in exclusion n°%d in position %d", i, j);
}
}
}
}
count++;
}
}
void noDuplicate( int arr[], int *size ) {
int i=0, j=0;
for (i = 1; i < *size; i++) {
if (arr[i] != arr[j]) {
j++;
arr[j] = arr[i];
}
}
*size = (j + 1);
}
void xclusion_alloc (int x, int y, int(**aptr)[x][y]) {
*aptr = malloc( sizeof(int[x][y]) );
assert(*aptr != NULL);
}
void xclusion_fill (int x, int y, int array[x][y]) {
int i, j;
for(i=0; i<x; i++) {
for(j=0; j<y; j++) {
scanf("%d", &array[i][j]);
}
}
}
void xclusion_print (int x, int y, int array[x][y]) {
int i,j;
for(i=0; i<x; i++) {
printf("\nExclusion n°%d :", i);
printf(" { ");
for(j=0; j<y; j++) {
printf("%d ", array[i][j]);
}
printf("}");
printf("\n");
}
}
Sadly the output i'm getting is like this :
How many exclusions :3
How many elements in each exclusion :2
5 3
2 7
4 1
Exclusion n░0 : { 5 3 }
Exclusion n░1 : { 2 7 }
Exclusion n░2 : { 4 1 }
How many elements do we have to keep :1
What are they :5
How many elements we can't use :1 2
What are they :
element to keep found in exclusion n░0 in position 0
Element 3 of exclusion 0 inserted in the array of elements we can't use
Our array of elements we can't use : 2
I managed to make it work by making the following changes to my function :
void interdiction(int **throwArr, int *throw_size, int *keepArr, int keep_size, int x, int y, int exclusionArr[x][y]){
int i, j, k, count=0;
while(count<keep_size){
for(i=0;i<x;i++) {
for(j=0;j<y;j++) {
if (exclusionArr[i][j] == keepArr[count]) {
for (k=0;k<y;k++){
if(k!=j){
printf("\nElement %d of exclusion %d inserted in the array of elements we can't use",exclusionArr[i][k], i);
(*throwArr)[*throw_size]=exclusionArr[i][k];
*throw_size+=1;
}
else printf("\nelement to keep found in exclusion n°%d in position %d", i, j);
}
}
}
}
count++;
}
}
Okay I think you need to change those lines as following. Also you made a mistake when you were testing your program.
void interdiction(int *throwArr, int throw_size, int *keepArr, int *keep_size, int x, int y, int exclusionArr[x][y]);
interdiction(throwArr, throw_size, keepArr, &keep_size, rexc, lexc, *exclusionArr);
void interdiction(int *throwArr, int throw_size, int *keepArr, int *keep_size, int x, int y, int exclusionArr[x][y]) {
...
throwArr[*throw_size]=exclusionArr[i][k]; // these two lines switched order
*throw_size+=1;
...
}

C - maximum value from one dimensional array's groups

So, my task is to let user fill one dimensional array A. This array has M number of groups and P members in each group. I need to fill array B with maximum values of each group in A array and display results of maximum values in each group after. I couldn't figure out any way to do it. I would really appreciate your help since I am a beginner programmer and doing my best to study. So my main problem in code is fillBArray function.
#include <stdio.h>
#include <stdlib.h>
int checkingvariable(int k, int a, int b);
void fillArray(int M, int P,int A[]);
void printArray(int M, int P,int A[]);
void fillBArray(int M, int P,int A[]);
int main()
{
int M, P;
printf("Enter M (the number of groups): ");
scanf("%d", &M);
M=checkingvariable(M, 1, 10);
printf("Enter P (the number of cars in one group): ");
scanf("%d", &P);
P=checkingvariable(P, 1, 10);
int i = P*M;
int A[i];
fillArray(M, P, A);
printArray(M, P, A);
fillBArray(M, P, A);
return 0;
}
void printArray(int M, int P,int A[])
{
int i;
for (i=0 ; i< M*P ; i++)
{
printf("%d ", A[i]);
printf("\n");
}
}
void fillArray(int M, int P, int A[])
{
int i;
for (i=0 ; i< M*P ; i++)
{
printf("Enter speed of car %d: ", i+1);
scanf("%d", &A[i]);
}
}
void fillBArray(int M, int P, int A[])
{
int c, k=0;
int maximum = A[0];
int B[M], group;
for (c = 0; c < P*M; c++)
{
if (A[c] > maximum)
{
maximum = A[c];
}
maximum = B[k];
printf("Maximum value for %d group is: %d", group, maximum);
}
}
int checkingvariable(int k, int a, int b)
{
if (k<a || k>b)
{
while(k<a || k>b)
{
printf("Enter correct value between %d and %d: ", a, b);
scanf("%d", &k);
}
}
return k;
}
One way is to replace one loop with two nested loops. The outer loop would iterate groups, while the nested loop would iterate members in each group.
One observation before you begin: members of a group g in the array A are located between indexes g*P, inclusive, and (g+1)*P, exclusive. Member m of a group is located at the index A[g*P + m].
Now it should be clear how to make your loops:
for (int g = 0 ; g != M ; g++) { // Groups
int max = A[g*P];
for (int m = 1 ; m != P ; m++) { // Members
... // Compute max
}
// Store max for group g in B[]
}
#include <stdio.h>
#include <stdlib.h>
int checkingvariable(int k, int a, int b);
void fillArray(int M, int P,int A[]);
void printArray(int M, int P,int A[]);
void fillBArray(int M, int P,int A[]);
int main()
{
int M, P;
printf("Enter M (the number of groups): ");
scanf("%d", &M);
M=checkingvariable(M, 1, 10);
printf("Enter P (the number of cars in one group): ");
scanf("%d", &P);
P=checkingvariable(P, 1, 10);
int i = P*M;
int A[i];
fillArray(M, P, A);
printArray(M, P, A);
fillBArray(M, P, A);
return 0;
}
void printArray(int M, int P,int A[])
{
int i;
for (i=0 ; i< M*P ; i++)
{
printf("%d ", A[i]);
printf("\n");
}
}
void fillArray(int M, int P, int A[])
{
int i;
for (i=0 ; i< M*P ; i++)
{
printf("Enter speed of car %d: ", i+1);
scanf("%d", &A[i]);
}
}
/*void fillBArray(int M, int P, int A[])
{
int c, k=0;
int maximum = A[0];
int B[M], group;
for (c = 0; c < P; c++)
{
if (A[c] > maximum)
{
maximum = A[c];
}
if (c < P)
{
group = 1;
maximum = A[c];
printf("Maximum value for %d group is: %d", group, maximum);
}
if (c < P*2)
{
group = 2;
k=1;
maximum = A[c];
printf("Maximum value for %d group is: %d", group, maximum);
}
}
}*/
void fillBArray(int M, int P, int A[])
{
int B[M], maximum = 0, m;
for (int g = 0 ; g != M ; g++)// Groups
{
int max = A[g*P];
for (m = 0 ; m != P ; m++) // Members
{
if (A[g*P + m] > maximum)
{
maximum = A[g*P + m];
}
}
B[g] = maximum;
printf("Maximum value for %d group is: %d", g+1, maximum);
printf("\n");
maximum = 0;
}
}
int checkingvariable(int k, int a, int b)
{
if (k<a || k>b)
{
while(k<a || k>b)
{
printf("Enter correct value between %d and %d: ", a, b);
scanf("%d", &k);
}
}
return k;
}
This is answer to my problem, check fillBArray.

Parallelization of Combination

I have got a piece of code that prints the combination of M number From N (nCm);
As it is a recursion, it works very slow when N is large.
#include <stdio.h>
#include <stdlib.h>
#define N 80
#define M 4
int result[M]= {0}; // THE ARRAY THAT SAVE THE RESULT OF ONE COMBINATION
int queue[N] = {0};
int top = 0;
void comb(int* input,int s, int n, int m)
{
if (s > n)
return ;
if (top == m)
{
for (int i = 0; i < m; i++)
{
result[i] = queue[i];
printf("%d\n", queue[i]);
}
}
queue[top++] = input[s];
comb(input,s+1, n, M);
top--;
comb(input,s+1, n, M);
}
int main()
{
int array[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,
27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,
50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,
73,74,75,76,77,78,79,80};
printf("\ncombination():\n");
comb(array,0, N, M);
printf("\n");
}
I would like to know if there is any space for improvement in the algorithm above?
if possible, can I use openMP ?
Thanks
To me your code was even giving the desired output. see
I have changed
printing format each combination was not good enough.
repeated combinations. (note: else part of if statement added).
reduced 2 recursive call with a loop and a recursive call. (Less space.)
The required code is:
#include <stdio.h>
#include <stdlib.h>
#define N 20
#define M 6
int result[M]= {0}; // THE ARRAY THAT SAVE THE RESULT OF ONE COMBINATION
int queue[N] = {0};
int top = 0;
void comb(int* input,int s, int n, int m)
{
if (s > n)
return ;
if (top == m)
{
printf("\n");
for (int i = 0; i < m; i++)
{
result[i] = queue[i];
printf("%d ", queue[i]);
}
}else{
for(int ss=s;ss<n;ss++){
queue[top++] = input[ss];
comb(input,ss+1, n, m);
top--;
}
//comb(input,s+1, n, m);
}
}
int main()
{
int array[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,
27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,
50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,
73,74,75,76,77,78,79,80};
printf("\ncombinations():\n");
comb(array,0, N, M);
printf("\n");
}

Resources