I've written this code for BFS, but after showing the result it crashes. I don't find anything wrong with my code. Here's the code
I think this is pointer related problem, because I got the same problem because I did not allocate memeory. Visual studio debugger shows there's a problem in this function.
int getAdjUnvisitedVertex(int vertexIndex) {
for (int j = 0; j < vertexCount; ++j) {
if (adjMatrix[vertexIndex][j] == 1 && vertices[j]->visited == false) { //Is there anything wrong in this logic?
return j;
}
}
return 0;
}
Any help will be much appreciated. This is my full code. DFS is working, its BFS that causing problems.
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<malloc.h>
#include<stdbool.h>
#define SIZE 50
int vertexCount;
struct vertex {
char label;
bool visited;
};
struct vertex *vertices[SIZE];
int adjMatrix[SIZE][SIZE];
int stack[SIZE];
int queue[SIZE];
int top = -1;
int front = -1;
int rear = -1;
void menu();
void addVertex();
void addEdges();
void push(char);
void pop();
void enQueue(char);
int deQueue();
void displayAdjMatrix();
void displayVertex(int);
int getAdjUnvisitedVertex(int);
void DFS();
void BFS();
bool isStackEmpty();
bool isQueueEmpty();
int main() {
menu();
addVertex();
addEdges();
puts("\nDepth first search:");
DFS();
puts("\nBreadth first search:");
BFS();
}
void menu() {
puts("How many vertices?");
scanf("%d", &vertexCount);
}
void addVertex() {
int ascii = (int)'A';
puts("Vertices are:");
for (int i = 0; i < vertexCount; ++i, ++ascii) {
vertices[i] = (struct vertex*)calloc(vertexCount, sizeof(struct vertex));
vertices[i]->label = (char)ascii;
vertices[i]->visited = false;
printf("%c ", vertices[i]->label);
}
}
void addEdges() {
puts("\nEnter edges:");
for (int i = 0; i < vertexCount; ++i) {
for (int j = i + 1; j < vertexCount; ++j) {
printf("%c->%c: ", vertices[i]->label, vertices[j]->label);
scanf("%d", &adjMatrix[i][j]);
if (adjMatrix[i][j] == 1) {
adjMatrix[j][i] = 1;
}
}
}
}
void displayAdjMatrix() {
for (int i = 0; i < vertexCount; ++i) {
for (int j = 0; j < vertexCount; ++j) {
printf("%d\t", adjMatrix[i][j]);
}
puts("");
}
}
void push(char data) {
if (top == SIZE - 1) {
puts("Overflow!");
return;
}
stack[++top] = data;
}
void pop() {
if (top == -1) {
puts("Underflow!");
return;
}
stack[top--];
}
int getAdjUnvisitedVertex(int vertexIndex) {
for (int j = 0; j < vertexCount; ++j) {
if (adjMatrix[vertexIndex][j] == 1 && vertices[j]->visited == false) {
return j;
}
}
return 0;
}
void displayVertex(int vertexIndex) {
printf("%c ", vertices[vertexIndex]->label);
}
void DFS() {
vertices[0]->visited = true;
displayVertex(0);
push(0);
while (!isStackEmpty()) {
int unvisitedVertex = getAdjUnvisitedVertex(stack[top]);
if (!unvisitedVertex) {
pop();
}
else {
vertices[unvisitedVertex]->visited = true;
displayVertex(unvisitedVertex);
push(unvisitedVertex);
}
}
for (int i = 0; i < vertexCount; ++i) {
vertices[i]->visited = false;
}
}
bool isStackEmpty() {
if (top == -1) {
return true;
}
return false;
}
bool isQueueEmpty() {
if (front == -1) {
return true;
}
return false;
}
void enQueue(char data) {
if (rear == SIZE - 1) {
puts("Queue is full!");
return;
}
if (front == -1) {
++front;
}
queue[++rear] = data;
}
int deQueue() {
if (front == - 1) {
puts("Queue is empty!");
return 0;
}
int deleted;
deleted = queue[front];
queue[front++] = 0;
return deleted;
}
void BFS() {
vertices[0]->visited = true;
displayVertex(0);
enQueue(0);
while (!isQueueEmpty()) {
int temp = deQueue();
int unvisitedVertex;
while(unvisitedVertex = getAdjUnvisitedVertex(temp)) {
vertices[unvisitedVertex]->visited = true;
displayVertex(unvisitedVertex);
enQueue(unvisitedVertex);
}
}
for (int i = 0; i < vertexCount; ++i) {
vertices[i]->visited = false;
}
}
Related
So, I'm trying to do an impletation of Sharing Suffixes WITHOUT USING UKKONNENS ALGORITHM (don't understand ukkonnens). So basicaly what I'd do is searching for a word in every node that isn't ending. However, when I try to debug it, it returns a negative value. I honestly don't know how to solve it, I made constant breakpoints so it would come out of the loop and not do as many iterations but it just keeps going.
I'm very new to C so for me this is a hard thing and I appreciate all the help.
#include "trie.h"
tree_t create_trie()
{
int i = 0;
tree_t node = (tree_t)malloc(sizeof(struct _node));
for(i = 0; i < 26; i++)
{
node->sons[i] = NULL;
}
node->ending = false;
return node;
}
void delete_trie(tree_t trie)
{
int i = 0;
for(i = 0; i < 26;i++)
{
if(trie->sons[i]!=NULL)
{
delete_trie(trie->sons[i]);
}
else
{
continue;
}
}
free(trie);
}
tree_t put_trie(tree_t trie, char* s)
{
int i = 0;
char* t = s;
tree_t aux = trie;
if(lookup_trie(trie, s))
return trie;
for(i = 0; t[i]!='\0'; i++)
{
int it = (int)((char)tolower(t[i]) - 'a'); //le index
printf("\niterator %d\n", it);
if(aux->sons[it] == NULL)
{
aux->sons[it] = create_trie();
//aux->sons[it]->s = (char *)malloc(sizeof(char*));
//printf("created tree");
}
aux = aux->sons[it];
}
aux->ending = true;
return trie;
}
bool lookup_trie(tree_t trie, char* s)
{
int i = 0;
char* t = s;
tree_t aux = trie;
for(i = 0; i<strlen(t); i++)
{
int it = (int)((char)tolower(t[i]) - 'a'); //le index
if(aux->sons[it] == NULL)
{
return false;
}
aux = aux->sons[it];
}
if(aux->ending)
{
return true;
}
return false;
}
void print_trie(tree_t trie)
{
int i = 0;
for(i = 0; i<26; i++)
{
if(trie->sons[i] == NULL)
{
continue;
}
else
{
printf("%c", ((char)(i) + 'a'));
print_trie(trie->sons[i]);
}
//print_trie(trie->sons[i])
printf("\n");
}
}
tree_t share_word(tree_t trie, tree_t auxiliar, char* s)
{
int x = 0, j = 0; //auxiliar to compare and for variable
printf("Share word debug\n");
/*if(!is_vide(trie))
return (tree_t)NULL;*/
printf("here");
printf("%s\n",s);
for(j=0; j<26; j++)
{
for(x = 0; x < strlen(s); x++)
{
int it = (int)((char)tolower(s[x]) - 'a');
printf("%d\n", it);
//if its null i'm gonna look into other nodes from the first for
if(trie->sons[j] == NULL)
{
continue;
}
if(trie->sons[j] == NULL)
{
break;
}
else if(trie->sons[it] == NULL) //might pose a problem
{
//if the node is empty, we just jump to the next iteration
if(lookup_trie(trie->sons[j], s)) //if the suffix is present, return the subtree
{
printf("Word belongs\n");
auxiliar = trie->sons[j]; //is auxiliar JUST A POINTER?
return auxiliar;
}
else //if not present, go again through the function
{
auxiliar = share_word(trie->sons[j], auxiliar, s);
}
}
else //trie->sons[it] not null
{
printf("iterator not null\n");
if(lookup_trie(trie->sons[it], s+x)) //if the word is present
{
return trie->sons[it];
}
}
}
}
return auxiliar;
}
tree_t put_word(tree_t trie, char *s)
{
int i = 0;
tree_t auxiliar = create_trie();
printf("Beggining\n");
//missing a condition so it doesnt add all the suffixes;
auxiliar = share_word(trie, auxiliar, s);
/*for(i = 0; i < strlen(s); i++)
{
int it = (int)((char)tolower(s[i]) - 'a');
auxiliar = share_word(trie, auxiliar, s + i); //should look for the suffixes;
if(auxiliar->sons[it] != NULL )
{
if(trie->sons[it] == NULL)
{
trie->sons[it] = create_trie();
trie->sons[it] = auxiliar;
return trie;
}
}
else
{
printf("Auxiliar null\n");
trie->sons[it] = create_trie(); //proceeds to the next iteration by creating the node
}
//}
trie = trie->sons[it];
}*/
return trie;
}
bool is_vide(tree_t trie)
{
int i =0;
for(i =0; i <26;i++)
{
if(trie->sons[i] != NULL)
{
return false;
}
else
{
return true;
}
}
return true;
}
bool leads_leaf(tree_t trie, char *s)
{
int i = 0;
tree_t aux = trie;
for(i = 0; i < strlen(s); i++)
{
int it = (int)((char)tolower(s[i]) - 'a');
aux = aux->sons[it];
if(i == (strlen(s) - 1) && aux->ending)
{
return true;
}
else
{
return false;
}
}
return false;
}
int main()
{
tree_t tree = create_trie();
tree = put_trie(tree, "abcd");
tree = put_word(tree, "decd");
delete_trie(tree);
return 0;
}
I tried testing putting a string in a single way (abcd) and then searching the string (decd), which would add d, e, and when it would go for c it would find the node of the first strings that leads to c -> d -> '\0'. However, it sometimes just keeps veryfing the same letter (d) and doesn't add it or it just never goes to the next (e).
I think there is a problem with the function put_word and how it calls the share suffixes multiple times.
I have created a program which takes as an input:
a number which determines the shape the user wants to be printed,lets say copies
a number which the determines the 'size' of the shape
and a number which determines how many times the shape will be printed..
What I have tried is a for loop in main() function below each 'if' but the copies are printed one down another..I also came up with the idea of printing the first line <'copies'> times with the necessary padding but that practice seems to be different for every shape (and yes I cannot implement this logic in my code)...What can I do?
/*
Version 5*/
#include <stdio.h>
#include <stdio.h>
int getchoice(void);
int getsize(void);
void oof(int size,int copies);
void printrhombus(int size);
void printrighttriangle(int size);
void printisoscelestriangle(int size);
void printspace(void);
void printsymbol(void);
void printnewline(void);
void printrowno(int i);
int getcopies(void);
int main(void)
{
int choice = 0;
int size;
int copies;
for(; (choice = getchoice()) != -1 ;)
{
size = getsize();
copies = getcopies();
if(choice == 0)
{
oof(size,copies);
}
else if(choice == 1)
{
printrhombus(size);
}
else if(choice == 2)
{
printrighttriangle(size);
}
else if (choice == 3)
{
printisoscelestriangle(size);
}
}
return 0;
}
int getchoice(void)
{
int choice;
printf("Please enter which shape you want to be printed (0-3):\n");
scanf("%d",&choice);
printf("Your choice is %d\n",choice);
return choice;
}
int getsize(void)
{
int size;
printf("Please enter the number of rows-the size of your shape:\n");
scanf("\n%d",&size);
printf("Your size is %d\n",size);
return size;
}
void oof(int size,int copies)
{
int i,j,k,l;
for(i = 0; i< size; i++)
{
for(l = 0; l<copies; l++)
{
for(j = 0;j<i;j++)
{
printsymbol();
}
}
for(k =0;k<size;k++)
{
if(k == 0 || i == 0 || k == size-1 || i == size-1)
{
printrowno(i);
}
else printsymbol();
}
printnewline();
}
}
void printrhombus(int size)
{
int i,j;
int rows1 = (size/2)+1;
for(i = 1;i<=rows1;i++)
{
for(j = 1;j<=((2*rows1)-1);j++)
{
if((j==(rows1+(i-1))) || j==(rows1-(i-1)))
{
printrowno(i);
}
else if(j>rows1+i-1)
{
printspace();
}
else if(j<rows1+i-1 && j!= rows1+1-i)
{
printsymbol();
}
}
printnewline();
}
for(i = rows1-1;i>=1;i--)
{
for(j=1;j<=((2*rows1)-1);j++)
{
if((j==(rows1+(i-1))) || j==(rows1-(i-1)))
{
printrowno(size-i+1);
}
else if(j>rows1+i-1)
{
printspace();
}
else if(j<rows1+i-1 && j!= (rows1+1-i))
{
printsymbol();
}
}
printnewline();
}
}
void printrighttriangle(int size)
{
int rowno,colno;
for(rowno = 1; rowno<=size; rowno++)
{
for(colno = 1; colno<= rowno; colno++)
{
if ((colno==1) || (rowno == size) || colno == rowno)
{
printrowno(rowno);
}
else if(colno>rowno)
{
printspace();
}
else
{
printsymbol();
}
}
printnewline();
}
}
void printisoscelestriangle(int size)
{
int i,j;
for(i = 1; i<= size; i++)
{
for(j = 1;j<= ((2*size)-1);j++)
{
if(j ==(size-(i-1)) ||j == (size+(i-1))|| i == size)
{
printrowno(i);
}
if (j<size-(i-1))
{
printspace();
}
if(j>(size-(i-1)) && j<(size +(i-1))&& i!= size)
{
printsymbol();
}
}
printnewline();
}
}
void printspace(void)
{
printf(" ");
return;
}
void printsymbol(void)
{
printf("-");
return;
}
void printrowno(int i)
{
printf("%d",i);
}
void printnewline(void)
{
printf("\n");
return;
}
int getcopies(void)
{
int copies;
printf("Please enter number of copies:\n");
scanf("\n%d",&copies);
return copies;
}
I don't understand why printq() function prints 0, but when I access it back in main() it prints. I don't understand what I am doing wrong, I tried using pointers, but I get some different error in the priority queue. I want to print elements in array pq[10].
EDIT: I realized that the elements are stored but when I use pq[R].data it prints
but when I use pq[i].data in printq() and put it inside for loop, it prints zero.
#include <stdio.h>
int F = -1, R = -1;
int item, max = 10;
struct prioq {
int data;
int prio;
};
struct prioq pq[10] = { 0 };
void printq()
{
int i = 0;
printf("%d,", pq[i].data);
printf("QUEUE :");
for (i = 0; i < max; i++) {
printf("%d,", pq[i].data);
}
printf("\n");
printf("PRIO :");
for (i = 0; i < max; i++) {
printf("%d,", pq[i].prio);
}
}
void enqueue(int item, int p, struct prioq pq[])
{
if (F == -1 && R == -1 || F > R) {
F == 0;
R == 0;
pq[R].data = item;
pq[R].prio = p;
printf("%d", pq[R].data);
printf("%d", pq[R].prio);
printq();
} else if (R == max-1 || R > max) {
printf("overflow\n");
} else if (R < max) {
R++;
pq[R].data = item;
pq[R].prio = p;
printq();
}
}
void dequeue(struct prioq pq[])
{
int large = 0;
if (F == -1) {
printf("underflow\n");
} else {
int i;
for (i = 0; i < max; i++) {
if (pq[i].prio > large) {
large = i;
}
}
}
item = pq[large].data;
pq[large].prio = 0;
pq[large].data = 0;
printf("item deleted: %d\n", item);
printq();
}
void main()
{
int item = 0;
int c = 0, p = 0;
do {
printf("choose your option\n");
printf("1.Insert, 2.Delete, 3.Exit\n" );
scanf("%d", &c);
switch (c) {
case 1:
printf("Enter the priority and element to insert\n");
scanf("%d %d", &item, &p);
enqueue(item,p,pq);
printf("%d", pq[R].data);
printf("%d", pq[R].prio);
break;
case 2:
dequeue(pq);
break;
default:
c = 3;
break;
}
} while (c != 3);
printf("exited\n");
}
In your enqueue function, change the == in the F and R assignments to =.
void enqueue(int item, int p, struct prioq pq[])
{
if (F == -1 && R == -1 || F > R) {
F = 0; // Here
R = 0; // And here
pq[R].data = item;
pq[R].prio = p;
printf("%d", pq[R].data);
printf("%d", pq[R].prio);
printq();
} else if (R == max-1 || R > max) {
printf("overflow\n");
} else if (R < max) {
R++;
pq[R].data = item;
pq[R].prio = p;
printq();
}
}
i'm an trying to write a program that will call a function win if there is n number of X's or O's in a row. I am have difficulty with the diagonal win that slopes upwards. can any offer any advice on what I should change? Thanks in advance. It calls an infinite loop instead of returning true.
bool left_diag_win(char **board, int num_rows, int num_cols) {
int i;
if (board[0][0] == '*') {
return false;
}
for (i = 1; i < num_rows; ++i) {
if (board[i][i] != board[0][0]) {
return false;
}
}
return true;
}
bool right_diag_win(char **board, int num_rows, int num_cols) {
int i;
if (board[0][num_cols - 1] == '*') {
return false;
}
for (i = 1; i < num_rows; ++i) {
if (board[i][num_cols - i - 1] != board[0][num_cols - 1]) {
return false;
}
}
return true;
}
You code seems correct, but you probably have a problem elsewhere. Here is an example where it behaves as expected:
#include <stdbool.h>
#include <stdio.h>
bool left_diag_win(char **board, int num_rows, int num_cols) {
if (board[0][0] == '*') {
return false;
}
for (int i = 1; i < num_rows; ++i) {
if (board[i][i] != board[0][0]) {
return false;
}
}
return true;
}
bool right_diag_win(char **board, int num_rows, int num_cols) {
if (board[0][num_cols - 1] == '*') {
return false;
}
for (int i = 1; i < num_rows; ++i) {
if (board[i][num_cols - i - 1] != board[0][num_cols - 1]) {
return false;
}
}
return true;
}
int main(void) {
char *matrix1[] = { "X****", "*X***", "**X**", "***X*", "****X" };
char *matrix2[] = { "****X", "***X*", "**X**", "*X***", "X****" };
printf("matrix:\n");
for (int i = 0; i < 5; i++) {
printf("%s\n", matrix1[i]);
}
printf("left-diagonal: %d\n", left_diag_win(matrix1, 5, 5));
printf("right-diagonal: %d\n\n", right_diag_win(matrix1, 5, 5));
printf("matrix:\n");
for (int i = 0; i < 5; i++) {
printf("%s\n", matrix2[i]);
}
printf("left-diagonal: %d\n", left_diag_win(matrix2, 5, 5));
printf("right-diagonal: %d\n\n", right_diag_win(matrix2, 5, 5));
return 0;
}
Output:
matrix:
X****
*X***
**X**
***X*
****X
left-diagonal: 1
right-diagonal: 0
matrix:
****X
***X*
**X**
*X***
X****
left-diagonal: 0
right-diagonal: 1
So I'm having trouble with Dijkstra's algorithm (src to dest). I looked at other answers and could not find the solution to my problem. I have used an adjacency list, thus I have a list for vertices, and each vertex has it's own edge list. My problem arises when I have a node that is unreachable. Specifically, it never gets visited thus I'm stuck in my allNotComp while loop. Can anyone help me with a solution? Code is below.
#include <stdlib.h>
#include <stdio.h>
int INFINITY = 9999;
struct edge
{
int vertexIndex;
int vertexWeight;
struct edge *edgePtr;
} edge;
struct vertex
{
int vertexKey;
struct edge *edgePtr;
struct vertex *vertexPtr;
}vertex;
struct vertex *Start = NULL;
void insertEdge(int vertex, int vertex2, int vertexWeight);
void insertVertex(int vertexKey);
int allNotComp(int comp[], int size);
void printPath(int prev[], int src, int dest, int size);
void dijkstra(int src, int size, int dest);
int cost(int curr, int i);
int main(int argc, char * argv[]) {
int k = 1;
int numVertices = atoi(argv[2]);
char* source = argv[3];
char* destination = argv[4];
int src = atoi(argv[3]);
int dest = atoi(argv[4]);
Start = &vertex;
Start->vertexKey = 0;
Start->vertexPtr = NULL;
Start->edgePtr = NULL;
int m = 0;
int flag = 0;
int flag2 = 0;
for(m = 0; m < numVertices; m++){
if(src == m) {
flag = 1;
}
if(dest == m) {
flag2 = 1;
}
}
if(!(flag && flag2)) {
printf("%s ", "ERROR: Src and/or Dest not valid.\n");
exit(0);
}
while(k < numVertices) {
insertVertex(k);
k++;
}
FILE *f = fopen(argv[1], "r");
int numbers[numVertices][numVertices];
char ch;
int i = 0;
int j = 0;
for(m = 0; m < numVertices*numVertices; m++) {
fscanf(f, "%d", &(numbers[i][j]));
j=j+1;
if(j == numVertices) {
i=i+1;
j=0;
}
}
for(i=0;i<numVertices;i++) {
for(j=0;j<numVertices;j++) {
if(i == j && numbers[i][j] != 0) {
printf("%s", "ERROR: All diagonals must be zero.\n");
exit(0);
}
if(i != j) {
insertEdge(i, j, numbers[i][j]);
}
}
}
dijkstra(src, numVertices, dest);
}
void insertEdge(int vertex, int vertex2, int vertexWeight)
{
if(vertexWeight == -1) return;
struct vertex *traverse;
if(vertex == Start->vertexKey) {
traverse = Start;
}
else {
while(traverse->vertexKey != vertex) {
traverse = traverse->vertexPtr;
}
}
struct edge *e,*e1,*e2;
e=traverse->edgePtr;
while(e&& e->edgePtr)
{
e=e->edgePtr;
}
e1=(struct edge *)malloc(sizeof(*e1));
e1->vertexIndex=vertex2;
e1->vertexWeight = vertexWeight;
e1->edgePtr=NULL;
if(e)
e->edgePtr=e1;
else
traverse->edgePtr=e1;
}
void insertVertex(int vertexKey) {
struct vertex *v, *v1, *v2;
v = Start->vertexPtr;
while(v && v->vertexPtr) {
v=v->vertexPtr;
}
v1=(struct vertex *)malloc(sizeof(*v1));
v1->vertexKey = vertexKey;
v1->vertexPtr = NULL;
v1->edgePtr = NULL;
if(v) {
v->vertexPtr = v1;
}
else {
Start->vertexPtr = v1;
}
}
void dijkstra(int src, int size, int dest) {
int comp[size];
int dist[size];
int prev[size];
int i;
for(i = 0; i<size; i++) {
comp[i] = 0;
dist[i] = INFINITY;
prev[i] = -1;
}
comp[src] = 1;
dist[src] = 0;
prev[src] = src;
int curr = src;
int k;
int minDist;
int newDist;
while(allNotComp(comp, size)) {
minDist = INFINITY;
for(i = 0; i<size;i++) {
if(comp[i] == 0) {
newDist = dist[curr] + cost(curr, i);
if(newDist < dist[i]) {
dist[i] = newDist;
prev[i] = curr; }
if(dist[i] < minDist) {
minDist = dist[i];
k=i; }
}
}
curr = k;
comp[curr] = 1;
}
if(dist[dest] < INFINITY) {
printPath(prev, src, dest, size);
printf(":%d\n", dist[dest]);
} else {
printf("%s\n", "NO PATH EXISTS BETWEEN THE TWO VERTICES!");
}
}
int allNotComp(int comp[], int size) {
int i;
for(i = 0; i < size; i++) {
if(comp[i] == 0) {
return 1;
}
}
return 0;
}
int cost(int curr, int i) {
struct vertex *travel;
struct edge *traverse;
travel = Start;
while(travel->vertexPtr != NULL) {
if(travel->vertexKey != curr) {
travel = travel->vertexPtr;
}
else{
break;
}
}
traverse = travel->edgePtr;
while(traverse->edgePtr != NULL) {
if(traverse->vertexIndex != i) {
traverse = traverse->edgePtr;
}
else{
break;
}
}
if(traverse->vertexIndex != i) {
return INFINITY;
}
return traverse->vertexWeight;
}
void printPath(int prev[], int src, int dest, int size) {
if(src == dest) {
printf("%d", src);
}
else {
printPath(prev, src, prev[dest], size);
printf("-%d", dest);
}
}
Although an unreachable node never gets visited, this situation can be detected. If the dists of all unvisited nodes are INFINITY, this means all remaining nodes are unreachable, and you should end the loop.