c/c++ 廣義表
阿新 • • 發佈:2018-07-05
string.h include src img info 作用 技術 如果 nio
廣義表
列表裏面有列表,比如(1,(2,(3,4)),5)
用鏈表可以實現
結果如圖
guangyibiao.h
#ifndef __GUANGYIBIAO__ #define __GUANGYIBIAO__ #include <stdio.h> #include <string.h> #include <memory.h> #include <malloc.h> #include <assert.h> #include <stdbool.h> #include <stdlib.h> #define AtomType int typedef enum{ATOM, LIST}ElemTag; typedef struct GLNode{ ElemTag tag; union{ AtomType atom; struct GLNode* head; }; struct GLNode* tail; }GLNode; typedef GLNode* GenList; void init(GenList* gl); void createGenList(GenList* gl, char* s); void show(GenList gl); #endif
guangyibiao.c
#include "guangyibiao.h" void init(GenList* gl){ *gl = NULL; } //挑出逗號前的一個元素,元素可以是原子也可以是列表 bool server1(char* sub, char* hsub){ int n = strlen(sub); int i = 0; char ch = sub[0]; int k = 0; //k的作用是,識別逗號是括號裏的,還是括號外的,如果是括號外的逗號就跳出while了,括號內的逗號不跳出循環,繼續往下找。 while(i < n && (ch != ‘,‘ || k != 0)){ if(ch == ‘(‘){ k++; } else if(ch == ‘)‘){ k--; } i++; ch = sub[i]; } //逗號在sub的範圍內 if(i < n){ sub[i] = ‘\0‘; strcpy(hsub, sub); strcpy(sub, sub+i+1); } //括號不匹配 else if(k != 0) return false; //sub本身就是表,比如為(1,2)時,i會等於n,所以把sub給hsub,sub就沒有以後部分了 else{ strcpy(hsub, sub); sub[0] = ‘\0‘; } return true; } //思路:遞歸創建節點,如果sub是列表,就遞歸調用自己 void createGenList(GenList* gl, char* s){ int n = strlen(s); //去掉s的外括號,比如s為(1,(2, 3)),處理後sub為1,(2, 3),並在sub的最後加上‘\0‘ char* sub = (char*)malloc(sizeof(char) * (n - 2)); char* hsub = (char*)malloc(sizeof(char) * (n - 2)); assert(NULL != sub && NULL != hsub); strncpy(sub, s+1, n-2); sub[n-2] = ‘\0‘; GLNode* p = *gl; while(strlen(sub) != 0){ if(NULL == p){ *gl = p = (GLNode*)malloc(sizeof(GLNode)); p->head = p->tail = NULL; }else{ p = p->tail = (GLNode*)malloc(sizeof(GLNode)); p->head = p->tail = NULL; } assert(NULL != p); if(server1(sub, hsub)){ if(hsub[0] == ‘(‘){ p->tag = LIST; createGenList(&(p->head), hsub); } else{ p->tag = ATOM; p->atom = atoi(hsub); } } } } //思路:遞歸 void show(GenList gl){ if(gl == NULL) return; if(gl->tag == ATOM){ printf("%d", gl->atom); if(gl->tail != NULL){ printf(","); } //如果gl為ATOM的話,gl就不會有head,所以只需調用show(gl->tail) show(gl->tail); } //如果gl為LIST的話,gl就會有head,也會有tail,所以調用show(gl->head),show(gl->tail) else if(gl->tag == LIST){ printf("("); show(gl->head); printf(")"); if(gl->tail != NULL){ printf(","); } show(gl->tail); } }
guangyibiaomai.c
#include "guangyibiao.h" int main(){ GenList gl; init(&gl); char* a = "(1,2,3)"; char* b = "(1,(2,3))"; char* c = "(1,(2),3)"; char* d = "((1,2),3)"; char* e = "((1,2,3))"; char* f = "((),1)"; char* g = "(1,(2,(3,4)),5)"; char* h = "((),1,(2,(3,(),4)),5)"; char* i = "(())"; createGenList(&gl, i); if(gl != NULL){ printf("("); show(gl); printf(")\n"); } return 0; }
c/c++ 廣義表