c - 从文件(C 语言)中读取整数,其中包括有向图的数据

标签 c file graph

假设我创建一个名为graph-file.txt的文件,其中包含一个

的数据

有向图如下:

7
{5, 2, 3}, {1,5}, {}, { }, {3}, { }, { }

文件的第一行显示顶点数(在本例中为 7)。 第二行描述每个顶点的邻居 N+(v)。例如,从顶点 1 开始,边被定向到顶点 5,2 和 3,而对于顶点 7,没有边被定向到该图中的任何其他顶点。

我想问一下如何从该文件中读取BFS算法所需的边信息(如上所述)?

我使用以下函数进行 BFS:

#define SIZE 40

struct queue {
    int items[SIZE];
    int front;
    int rear;
};

struct queue* createQueue();
void enqueue(struct queue* q, int);
int dequeue(struct queue* q);
void display(struct queue* q);
int isEmpty(struct queue* q);
void printQueue(struct queue* q);

struct node
{
    int vertex;
    struct node* next;
};

struct node* createNode(int);

struct Graph
{
    int numVertices;
    struct node** adjLists;
    int* visited;
};

struct Graph* createGraph(int vertices);
void addEdge(struct Graph* graph, int src, int dest);
void printGraph(struct Graph* graph);
void bfs(struct Graph* graph, int startVertex);


void bfs(struct Graph* graph, int startVertex) {

    struct queue* q = createQueue();

    graph->visited[startVertex] = 1;
    enqueue(q, startVertex);

    while(!isEmpty(q)){
        printQueue(q);
        int currentVertex = dequeue(q);
        printf("Visited %d\n", currentVertex);

       struct node* temp = graph->adjLists[currentVertex];

       while(temp) {
            int adjVertex = temp->vertex;

            if(graph->visited[adjVertex] == 0){
                graph->visited[adjVertex] = 1;
                enqueue(q, adjVertex);
            }
            temp = temp->next;
       }
    }
}


struct node* createNode(int v)
{
    struct node* newNode = malloc(sizeof(struct node));
    newNode->vertex = v;
    newNode->next = NULL;
    return newNode;
}


struct Graph* createGraph(int vertices)
{
    struct Graph* graph = malloc(sizeof(struct Graph));
    graph->numVertices = vertices;

    graph->adjLists = malloc(vertices * sizeof(struct node*));
    graph->visited = malloc(vertices * sizeof(int));


    int i;
    for (i = 0; i < vertices; i++) {
        graph->adjLists[i] = NULL;
        graph->visited[i] = 0;
    }

    return graph;
}

void addEdge(struct Graph* graph, int src, int dest)
{
    // Add edge from src to dest
    struct node* newNode = createNode(dest);
    newNode->next = graph->adjLists[src];
    graph->adjLists[src] = newNode;

    // Add edge from dest to src
    newNode = createNode(src);
    newNode->next = graph->adjLists[dest];
    graph->adjLists[dest] = newNode;
}

struct queue* createQueue() {
    struct queue* q = malloc(sizeof(struct queue));
    q->front = -1;
    q->rear = -1;
    return q;
}


int isEmpty(struct queue* q) {
    if(q->rear == -1) 
        return 1;
    else 
        return 0;
}

void enqueue(struct queue* q, int value){
    if(q->rear == SIZE-1)
        printf("\nQueue is Full!!");
    else {
        if(q->front == -1)
            q->front = 0;
        q->rear++;
        q->items[q->rear] = value;
    }
}

int dequeue(struct queue* q){
    int item;
    if(isEmpty(q)){
        printf("Queue is empty");
        item = -1;
    }
    else{
        item = q->items[q->front];
        q->front++;
        if(q->front > q->rear){
            printf("Resetting queue");
            q->front = q->rear = -1;
        }
    }
    return item;
}

void printQueue(struct queue *q) {
    int i = q->front;

    if(isEmpty(q)) {
        printf("Queue is empty");
    } else {
        printf("\nQueue contains \n");
        for(i = q->front; i < q->rear + 1; i++) {
                printf("%d ", q->items[i]);
        }
    }    
}

最佳答案

假设输入有效,作为一个有趣的练习,我尝试提出所需的最小解析器。对于 x86_64,它编译为 less than 40 instructions ,使用一些寄存器:

void edge(int from, int to);

void parse(void)
{
    int v = 0;
    for (;;) {
        const int c = getchar();
        if (c == EOF)
            return;

        // Next 'from' vertex?
        if (c == '{') {
            ++v;
            continue;
        }

        // Ignore vertex count
        if (v == 0)
            continue;

        // Found 'to' vertex?
        int w = c - '0';
        if (w < 0 || w > 9)
            continue;

        // Parse 'to' vertex
        for (;;) {
            const int d = getchar() - '0';
            if (d < 0 || d > 9)
                break;
            w = w * 10 + d;
        }

        edge(v, w);
    }
}

当然,如果您需要验证输入,那么您将需要更多状态来处理逗号、右大括号、不匹配的顶点数、超出范围的顶点数、无效字符等。

关于c - 从文件(C 语言)中读取整数,其中包括有向图的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50541761/

相关文章:

file - 如何在不相互比较的情况下发现相同的文件?

java - 在 Java 中读取/打开文本文件

java - PDF 字节数组到 Android 应用程序中的 pdf 文件显示

html - 可以使用 mySQL 数据创建 Canvas 吗?

c - 在C中将函数之间的多个变量返回到

c - 如何在 C 中创建一个验证用户输入的函数?

c - 引用结构中的变量

c - memset 的速度 vs 直接赋值给零

mysql - 图表 Sonar Qube 数据库

javascript - 在 Highcharts 图表中动态定位文本和圆圈?