简体   繁体   English

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

[英]reading integers from a file (in C) which including data of a directed graph

Suppose I create a file named graph-file.txt , which including data of a 假设我创建了一个名为graph-file.txt的文件,其中包含

directed graph as the following: 有向图如下:

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

The first line of the file shows the number of vertices (7 in that case). 文件的第一行显示了顶点数(在这种情况下为7)。 The second line describes the neighbours N+(v) for each vertex. 第二行描述每个顶点的邻居N +(v)。 For example, from vertex number 1 edges are directed to vertices 5,2 and 3, and for vertex number 7 no edges are directed to any of the other vertices in that graph. 例如,从第1个顶点开始,边被指向顶点5,2和3,而对于第7个顶点,没有边指向该图中的任何其他顶点。

I would like to ask what is the way to read from that file the information about the edges (described above), which needed for BFS algorithm ? 我想问一下从该文件读取有关边的信息(如上所述)的方法,BFS算法需要哪些信息?

I use the following functions for 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]);
        }
    }    
}

Assuming the input is valid, as a fun exercise, I tried to come up with the minimal parser required. 假设输入是有效的,作为一个有趣的练习,我尝试提出所需的最小解析器。 For x86_64, it compiles down to less than 40 instructions , using a handful of registers: 对于x86_64,它使用少量寄存器将其编译为少于40条指令

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);
    }
}

Of course, if you need to validate the input, then you will need some more states to take care of the commas, closing braces, mismatching number of vertices, out of range vertex numbers, invalid characters, etc. 当然,如果需要验证输入,则将需要更多状态来处理逗号,右括号,顶点数量不匹配,超出范围的顶点数量,无效字符等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM