c - 通用链表:每当出现左括号时添加子链接
问题描述
这是我为字符串输入生成 GLL 的代码:a,(b,c),d 其中 (b,c) 将作为子项链接到 a 的下一个链接。
GLL* generateList(char poly[])
{
GLL* newNode = NULL, *first = NULL, *ptr = NULL;
while (poly[i] != '\0')
{
if (poly[i] == ')')
{
return first;
}
else
{
if (poly[i] != ',')
{
if (poly[i] != '(')
{
newNode = createNode(poly[i], 0);
}
else
{
++i;
newNode = createNode('#', 1);
newNode->dlink = generateList(poly);
}
}
}
if (first != NULL)
{
ptr = first;
while (ptr->next != NULL)
{
ptr = ptr->next;
}
ptr->next = newNode;
}
else
{
first = newNode;
}
i++;
}
return first;
}
这是我用于每个节点的结构。
typedef struct gll
{
int tag;
struct gll* next;
char data;
struct gll* dlink;
} GLL;
每当括号打开时,我都找不到将子链接添加到父链接的方法。程序循环运行。
注意:我已经将 i=0 声明为一个全局变量来保存字符的位置。
编辑:这是 createNode 函数
GLL* createNode(char value, int flag)
{
GLL* newNode;
newNode = (GLL *) malloc(sizeof(GLL)*1);
newNode->data = value;
newNode->dlink = NULL;
newNode->tag = flag;
newNode->next = NULL;
return newNode;
}
解决方案
那我该怎么做呢?
你可以这样做:
#include <stdbool.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct gll
{
int tag;
struct gll* next;
char data;
struct gll* dlink;
} GLL;
GLL* createNode(char value, int flag)
{
GLL* newNode = calloc(1, sizeof(*newNode));
if (!newNode)
return NULL;
newNode->tag = flag;
newNode->data = value;
return newNode;
}
void freeList(GLL *list)
{
for (GLL *current_node = list, *temp; current_node; current_node = temp) {
temp = current_node->next;
freeList(current_node->dlink);
free(current_node);
}
}
GLL* generateList(char *poly, size_t *pos)
{
size_t const length = strlen(poly);
GLL *head = NULL;
GLL *tail = NULL;
for (; *pos < length; ++*pos) {
if (poly[*pos] == '(') {
++*pos; // don't have the next called generateList() read '(' again
tail->dlink = generateList(poly, pos);
if (!tail->dlink) {
freeList(head);
return NULL;
}
continue;
}
else if (poly[*pos] == ')') {
return head;
}
else if (isalpha((char unsigned)poly[*pos])) {
if (!head) {
head = tail = createNode(poly[*pos], 0);
}
else {
tail->next = createNode(poly[*pos], 0);
tail = tail->next;
}
continue;
}
else if (poly[*pos] == ',')
continue;
fputs("Format error :(\n\n", stderr);
freeList(head);
return NULL;
}
return head;
}
void printList(GLL *list)
{
for (GLL *node = list; node; node = node->next) {
printf("%c ", node->data);
if (node->dlink) {
putchar('(');
printList(node->dlink);
printf("\b) ");
}
}
}
int main(void)
{
size_t pos = 0;
GLL *list = generateList("a,(b,(c,d,e(f)),g,h),i,j,k", &pos);
printList(list);
putchar('\n');
freeList(list);
}
输出
a (b (cde (f)) gh) ijk
此外,如果 flag 为真,则表示不考虑数据,但有要链接的子列表。
抱歉,如果节点没有数据,我不明白怎么会有子列表。
推荐阅读
- python - openpyxl 只读模式不能 iter_cols
- python - 熊猫数据透视表输出具有整数和浮点数
- python - 数据库中不存在表“登录”
- python - 为什么re.sub在python中替换后添加空格?如何摆脱空间?
- java - 在 Java 进程中使用 Micrometer 计时器?
- rabbitmq - Yocto 项目 rabbitmq-server 配方构建
- c++ - 为什么在使用 lambda 递归时总是需要 [&]?
- c# - Java 验证签名 C# 等效
- javascript - 在 Console 日志的返回值中返回 undefiend
- laravel - 在laravel中以多种形式验证组中的至少一个复选框