I am supposed to convert a given adjacency matrix to an adjacency list in C. I need this adjacency list because this is where I will implement my algorithm for Depth First Search (DFS). Before I write my code for DFS, I wanna make sure that I made the right adjacency list. However, my problem is that when I try to run my code, the program does not proceed in printing the graph. I believe it's because of how I read user inputs because that is exactly where the program stops. Now my question is, how do I read multiple inputs in one line? I tried using fgets() but my program does not proceed in printing the graph/adjacency list. Provided below is the code that I wrote.
Here are the struct nodes:
typedef struct vertexnode VertexNode;
struct vertexnode
{
int vertex;
VertexNode *Next;
};
typedef struct graph
{
int numVertices;
VertexNode **adjLists;
} Graph;
Below is the main function:
int main()
{
int size, i, temp;
//char input1[100000];
scanf("%d\n", &size); // scan number of vertices
Graph *graph = createAGraph(size);
for(i = 0; i < size; i++) // scan the adjacency MATRIX
{
char input1[100000];
int j = 0;
fgets(input1, sizeof(input1), stdin);
char *piece = strtok(input1, " "); // extract first number
while(piece != NULL)
{
temp = atoi(piece); // convert from char to int
if(temp == 1) // create new node
{
addEdge(graph, i, j); //add edge from vertex i to j
}
j++;
piece = strtok(NULL, " ");
}
}
printGraph(graph);
return 0;
}
Function for creating a vertex:
VertexNode *createVertex(int vertexNum)
{
VertexNode *new_vertex = (VertexNode *) malloc(sizeof(VertexNode));
new_vertex->vertex = vertexNum + 1;
new_vertex->Next = NULL;
return new_vertex;
}
Function for creating the graph:
Graph *createAGraph(int size)
{
Graph *graph = (Graph *)malloc(sizeof(Graph));
graph->numVertices = size;
graph->adjLists = (VertexNode **)malloc(sizeof(VertexNode *));
for(int i = 0; i < size; i++)
graph->adjLists[i] = NULL;
return graph;
}
Function for addEdge:
void addEdge(Graph *graph, int s, int d)
{
VertexNode *newNode = createVertex(d);
newNode->Next = graph->adjLists[s];
graph->adjLists[s] = newNode;
}
Function for printing the adjacency list:
void printGraph(Graph *graph)
{
for(int i = 0; i < graph->numVertices; i++)
{
VertexNode *temp = graph->adjLists[i];
printf("\n Vertex %d\n: ", i+1);
while(temp)
{
printf("%d -> ", temp->vertex);
temp = temp->Next;
}
newline;
}
}
Is there a better way of taking a user input given the context that we have to read multiple inputs in a line and there's an arbitrary number of lines?
Example Input:
4
0 0 1 0
1 0 0 1
1 1 0 1
0 1 0 0
First input is the number of vertices in the list
The succeeding lines represent the adjacency matrix
The adjacency list should be like this:
1 -> 3
2 -> 1 -> 4
3 -> 1 -> 2 -> 4
4 -> 2
Would you please try the following:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main()
{
int i, j, size;
char *tk; // pointer to a token
char delim[] = " "; // delimiter of tokens
char line[BUFSIZ];
int *m; // matrix
fgets(line, BUFSIZ, stdin); // read stdin and assign line
size = atoi(line); // size of matrix
if (NULL == (m = malloc(sizeof(int) * size * size))) {
// allocate a matrix
fprintf(stderr, "malloc failed\n");
exit(1);
}
for (i = 0; i < size; i++) {
if (NULL == fgets(line, BUFSIZ, stdin)) {
fprintf(stderr, "insufficient lines\n");
exit(1);
}
j = 0;
tk = strtok(line, delim);
while (tk != NULL) {
m[i * size + j] = atoi(tk); // assign element of matrix
j++;
if (j > size) {
fprintf(stderr, "too many columns\n");
exit(1);
}
tk = strtok(NULL, delim);
}
if (j < size) {
fprintf(stderr, "insufficient columns\n");
exit(1);
}
}
// print the adjacency list
for (i = 0; i < size; i++) {
printf("%d", i + 1);
for (j = 0; j < size; j++) {
if (m[i * size + j]) {
printf(" -> %d", j + 1);
}
}
printf("\n");
}
return 0;
}
As I'm not aware of your special functions such as createAGraph() or
addEdge(), I've used my own definition of matrix. Please modify
my code to meet your interfaces.
Related
I have a C program where a CSV file containing 8 x,y coordinates are inserted into a linked list.
Each of the 8 coordinates belongs in a 2x2 grid. There are 4 grids as seen in the picture below:
First I want my program to determine which coordinate belongs in which grid. Once I've determined that, for each grid, I want to sum all of the x-coordinates and y-coordinates. Then for each grid 1-4, I want to then print the total sum of the x coord and y coord.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/time.h>
#include <string.h>
#define MAX 200
struct wake {
double x, y;
struct wake *next;
}*head;
typedef struct {
double x, y;
} grid_t;
typedef struct wake data;
void read_csv();
void gridSearch();
void maxNode();
int main(int argc, char *argv[]) {
read_csv();
}
void read_csv() {
// Opens the CSV datafile
FILE *fp = fopen("data4.csv", "r");
char buffer[MAX];
struct wake** tail = &head;
while (fgets(buffer, MAX, fp)) {
data *node = malloc(sizeof(data));
node->x = atof(strtok(buffer, ","));
node->y = atof(strtok(NULL, ","));
node->next = NULL;
*tail = node;
tail = &node->next;
}
gridSearch();
//maxNode();
}
void gridSearch() {
struct wake *current = head;
int i, j, gridnum = 0;
grid_t (*grid)[2] = calloc(4, sizeof(grid_t[2][2]));
//double min;
if(head == NULL) {
printf("List is empty \n");
}
else {
//Initializing min with head node data
while(current != NULL){
for (j = 0; j < 2; j++) {
for (i = 0; i < 2; i++) {
if ((current->x >= -2+i*2) && (current->x <= -2+(i+1)*2)) {
if ((current->y >= -2+j*2) && (current->x <= -2+(j+1)*2)) {
printf("%lf\n", current->x);
grid[i][j].x += current->x;
grid[i][j].y += current->y;
}
}
}
}
current= current->next;
}
}
for (i = 0; j < 2; j++) {
for (j = 0; i < 2; i++) {
gridnum++;
printf("Sum of x coord in grid %d: %lf\n", gridnum, grid[i][j].x);
printf("Sum of y coord in grid %d: %lf\n\n", gridnum, grid[i][j].y);
}
}
}
When I run my program, nothing seems to happen. I'm not sure why it's not working.
Here is the input CSV file:
-1,-1
-1,1.5
1,-1
1,1
-1.5,-1.5
-1,0.5
1.5,-1.5
0.5,0.5
I've been tasked with implementing Prim's algorithm to find the MCST using an adjacency matrix to represent the graph, and a struct to hold the MCST. The program takes in a file input, applies the algorithm and then outputs the minimum cost spanning tree. I got the program to take a file input and produce output, but the values I am getting are incorrect and look like dummy values to me.
My assumption is that the error occurs in either how I am storing the file input in my array, or in the algorithm itself. I've spent a good 12-15 hours troubleshooting this issue and am hoping someone can provide insight. The program is written in C and compiled with make in the format ./a6 <file>. I take and store the file input in my main() and then the methods are used in the order they are called. Below is an example my professor provided. The first line contains info about the vertices being entered and the remaining lines contain the actual data itself.
input:
6 10 0 <<--(size, edges, start)
0 1 16 <<--(from, to, weight)
0 5 21
0 4 19
1 2 5
1 3 6
1 5 11
2 3 10
3 4 18
3 5 14
4 5 33
output:
0 1 16 <<--(first edge)
1 2 5
1 3 6
1 5 11
3 4 18
total cost: 56
My code:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h> /* for INT_MAX */
#define N 10 /* max matrix size is 10 x 10 */
#define INF 9999
int cost = 0;
typedef struct lnode {
int fromv;
int tov;
int weight;
struct lnode *next;
} lnode;
int insertnode(lnode **lst, int from, int to, int wt);
void prims(int amtrx[][N],int n, lnode **lst);
void printpaths(lnode **lst);
void freelist(lnode **lst);
int isValid(int a, int b, int select[]);
int insertnode(lnode **lst, int from, int to, int wt){
lnode *newnode;
newnode = (lnode *) malloc(sizeof(struct lnode));
newnode->fromv = from;
newnode->tov = to;
newnode->weight = wt;
newnode->next=NULL;
if(*lst == NULL){
newnode -> next = *lst;
*lst = newnode;
} else {
lnode *current;
current = *lst;
while(current->next != NULL){
current = current->next;
}
newnode->next = current->next;
current->next = newnode;
}
return 1;
}
int isValid(int a, int b, int select[]){
if(a == b) return 0;
if(select[a] == 0 && select[b] == 0) return 0;
else if (select[a] == 1 && select[b] == 1) return 0;
return 1;
}
void prims(int amtrx[][N], int n, lnode **lst){
int i, j, row, col, edges_seen, min;
int select[N] = {0};
edges_seen = 0;
select[n] = 1;
while(edges_seen < N-1){
min = INF;
row = -1;
col = -1;
for(i = 0; i < N; i++) {
for(j = 0; j < N; j++){
if(amtrx[i][j] < min) {
if(isValid(i, j, select) == 1){
min = amtrx[i][j];
row = i;
col = j;
}
}
}
}
if(row != -1 && col != -1){
select[col] = 1;
select[row] = 1;
cost = cost + min;
insertnode(lst, row, col, min);
edges_seen++;
}
for(i = 0; i < N; i++){
printf("%3d", select[i]);
}
puts("\n\n");
}
}
void printpaths(lnode **lst){
lnode *current;
current = *lst;
while(current != NULL) {
printf("%4i ",current->fromv);
printf("%4i ", current->tov);
printf("%4i \n", current->weight);
current = current->next;
}
printf("\ntotal cost: %4i\n", cost);
}
void freelist(lnode **lst) {
lnode *temp = NULL;
while(*lst != NULL)
{
temp = *lst;
*lst = (*lst)->next;
free(temp);
}
}
int main(int argc, char **argv){
FILE *f = fopen(argv[1], "r");
lnode *lst;
lst = (lnode *)malloc(sizeof(struct lnode));
int i, j, nsz, nedg, fr, to, vtx, wt;
vtx = 1111;
nedg = 999;
nsz = 100;
fscanf(f, "%d %d %d", &nsz, &nedg, &vtx);
int amtrx[nsz][N];
for(i = 0; i < nsz; i++){
for(j = 0; j < nsz; j++){
amtrx[i][j] = INF;
}
}
for(i = 0; i < nedg; i++){
fscanf(f, "%d %d %d", &fr, &to, &wt);
amtrx[fr][to] = wt;
amtrx[to][fr] = wt;
}
fclose(f);
prims(amtrx, vtx, &lst);
printpaths(&lst);
freelist(&lst);
return EXIT_SUCCESS;
}
This code does not give any errors but displays the array with old
values without sorting by name field, it works up to reading the txt file storing data in a struct array student an instance of struct person, then when used the code to sort it and print the results of sorted array . but it does not work
#include < stdio.h >
#include < string.h >
int main() {
// read data from txt file and stores
// in a struct array
storeInarraySort();
}
int storeInarraySort() {
// struct person with 4 fields
struct person {
char name[100];
char address[100];
char IDnumber[20];
int age;
};
FILE * file = fopen("personout.txt", "r");
// declares an struct array to store data
struct person student[10];
int k = 0;
if (file != NULL)
{
char line[128]; /* or other suitable maximum line size */
/* read a line */
while (fgets(line, sizeof line, file) != NULL)
{
// stores values in struct array
sscanf(line, " %99[^,], %99[^,], %19[^,], %d", student[k].name,
student[k].address, student[k].IDnumber, & student[k].age);
k++;
}
printf("%d\n", k); // no of records in array
fclose(file);
// number of records k r=k first for loop
// inner for loop s=r+1
//char temp;
//struct person temp;
for (int r = 0; r < k - 1; r++) {
for (int s = r + 1; r < k; r++) {
if (strcmp(student[r].name, student[s].name) > 0) {
struct person temp = student[r];
//strcpy(temp,student[r]);
student[r] = student[s];
//strcpy(student[r],student[s]);
student[s] = temp;
//strcpy(student[s],temp);
}
}
}
// prints struct array to check
for (int t = 0; t < k; t++) {
printf("%s\n %s\n %s\n %d\n ", student[t].name,
student[t].address, student[t].IDnumber, student[t].age);
}
}
}
Use selection sort for sorting.
void swap(int *xp, int *yp)
{
int temp = *xp;
*xp = *yp;
*yp = temp;
}
void selectionSort(int arr[], int n)
{
int i, j, min_idx;
// One by one move boundary of unsorted subarray
for (i = 0; i < n-1; i++)
{
// Find the minimum element in unsorted array
min_idx = i;
for (j = i+1; j < n; j++)
if (strcmp(arr[j].name , arr[min_idx].name) < 0)
min_idx = j;
// Swap the found minimum element with the first element
swap(&arr[min_idx], &arr[i]);
}
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
//#include<igraph.h>
#define NUM_VERTICES1 15000// No. of data for Newman Watts to be used 15000:
//#define strings 10 // No. of base strings to be used 160:
//Function for generating infection rate randomly:
void unifRand(double *x, double *x1, double *x2)
{
int i;
const int n = 200; // 20
srand(unsigned(time(NULL)));
for(i = 0; i < n - 1; i++)
{
//x2[i] = rand()/double(RAND_MAX); //generate random number for choosing the infected neighbors(m):
x[i] = (0.2)+(0.4-0.2)*rand()/double(RAND_MAX);
x2[i] = 0.02; // fix the neighbor m and check:
x1[i] = log(1-x[i]);// Infection rate lambda:
printf("%lf\t%lf\t%lf\t%d\t%d\t\n", x[i], x1[i],x2[i],rand(), RAND_MAX);
}
}
// Function 2:
struct Edge {
int vertex;
struct Edge * next;
};
// Inserts Node to the Linked List by Head Insertion - O(1)
// Returns address of head which is the newly created node.
struct Edge * addEdge(struct Edge * currentHead, int newVertex)
{
struct Edge * newHead
= (struct Edge *) malloc(sizeof(struct Edge));
newHead->vertex = newVertex;
newHead->next = currentHead;
return newHead;
}
int main()
{
FILE *wg = NULL;
FILE *ob = NULL;
wg = fopen("ncwang1.txt","w");
ob = fopen("obs.txt","w");
if(wg == NULL)
{
printf("Error in opening file wg!\n");
}
if(ob == NULL)
{
printf("Error in opening file ob!\n");
}
int vertices = 200, edges = 400, i; // 20,50:(100,50)
int strings = 160;
int nobs = 10;
int v1, v2;
double j;
int k;
double t=0.0;
double dt=0.1;
double b;
double x[vertices], x1[vertices];
double x2[vertices];
unifRand(x,x1,x2);
// printf("Enter the Number of Vertices -\n");
// scanf("%d", &vertices);
//printf("\nEnter the Number of Edges -\n");
// scanf("%d", &edges);
struct Edge * adjacencyList[vertices + 1];
// Size is made (vertices + 1) to use the
// array as 1-indexed, for simplicity
// initialize array:
for (i = 0; i <= vertices; ++i) {
adjacencyList[i] = NULL;
}
for (i = 0; i <= edges; ++i) {
//scanf(%d%d", &v1, &v2);
v1 = rand()%200;
v2 = rand()%200;
// Adding edge v1 --> v2
// Add edge from v1 --> v2
if(v1 != v2)
adjacencyList[v1] = addEdge(adjacencyList[v1], v2);
// Adding edge v2 --> v1
// Remove this if you want a Directed Graph
adjacencyList[v2] = addEdge(adjacencyList[v2], v1);
}
// Printing Adjacency List
printf("\nAdjacency List -\n\n");
for(j = 0; j < strings; j++){
for (i = 0; i <= vertices; ++i) {
printf("adjacencyList[%d] -> ", i);
struct Edge * traverse = adjacencyList[i];
while (traverse != NULL)
{
b = (double)j/vertices;
fprintf(wg,"%d \t%d \t\t%0.6lf\t\t%0.1lf\t\t%0.8lf\t\n", i, traverse->vertex,-(x1[i]*(traverse->vertex))/100,b,
x[i]);
//fprintf(ob,"%d\t%0.2lf\t%0.1lf\n",k,(-log(1-x[i])*(traverse->vertex)),b);
printf("%d -> ", traverse->vertex);
traverse = traverse->next;
}
printf("NULL\n");
}
}
return 0;
fclose(wg);
fclose(ob);
wg = NULL;
ob = NULL;
}
I have written the above code for a network reconstruction performance from a reseach paper. I have to plot 'b' versus (-log(1-x[i])*(traverse->vertex)) from the output. The authors of the paper have mentioned that "the results are obtained by ensemble averaging over 10 independent realizations. How I can implement this in my code. As I am new to statistical physics, I do not know how to implement. Any suggestions will be helpful. The current output gives only a single line at b = 0.1, 0.2..1.0 which is not the expected output.c
i am trying to implement a linked-list in C with the aim to do a BFS on it.
The input for the list should look like this:
a-bc
b-a
c-a
which represents a list looking like this:
a
/ \
b c
now, my problem is that I cannot read the variable name defined in my Vertex struct. My program segfaults with Access Reading Violation. While printf("%s", s) takes a char *, casting the name to a char* doesn't help. The error takes place before the char is even accessed?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Vertex Vertex;
typedef struct Vertex
{
char name;
int visited;
int distance;
Vertex* next;
} Vertex;
struct Vertex* AddVertex(Vertex* head, char newVertexName)
{
Vertex* newHead = malloc(sizeof(Vertex));
newHead->name = newVertexName;
printf("added vertex named: %s", newHead->name); // causing the error
newHead->next = head;
newHead->visited = 0;
newHead->distance = 0;
return newHead;
}
int main()
{
// BFS
char s[100];
int l = 0;
const int nNrOfVerts = 27;
Vertex* adjList[28];
// initialise array of pointers
for(int i = 0; i <= nNrOfVerts; ++i)
{
adjList[i] = NULL;
}
// fill vertices with user data
for(int i = 1; i <= nNrOfVerts; ++i)
{
printf("enter %d vert: ", i);
if(scanf("%s", &s) != 1)
{
break;
}
l = strlen(s);
if(l > 2)
{
for(int k = 0; k < l; ++k)
{
// increment to accustom for the - seperator
if(1 == k)
{
k = 2;
}
adjList[i] = AddVertex(adjList[i], s[k]);
}
}
for(int k = 0; k < 100; ++k)
{
s[k] = NULL;
}
}
bfs(adjList);
// printing the list
for(int i = 1; i <= l; ++i)
{
for(int j = 0; j <= nNrOfVerts; ++j)
{
if(adjList[j]->distance == i)
{
printf("Level: %d is: %s", i, adjList[j]->name);
}
printf("No node for dist: %d", i);
}
}
return 0;
}
How can I access the value of newHead->name or adjList[i]->name for that matter? The interesting thing is, if I try to access adjList[i]->distance the correct integer is returned...
You declared name as a char but then you try to print it as a character :
printf("added vertex named: %s", newHead->name);
Change the %s to %c :
printf("added vertex named: %c", newHead->name);
or change your name to a char *.