C++어떻게 광의 표 의 상세 한 설명 을 실현 합 니까?
위의 그림 에서 볼 수 있 듯 이 광의 표 의 노드 유형 은 모두
head
,value
,sub
세 가지 가 있다.여기 서 매 거 진 유형 을 설정 하고 매 거 진 변 수 를 이용 하여 각 노드 의 유형 을 기록한다.
enum Type
{
HEAD, //
VALUE, //
SUB, //
};
모든 노드 는 자신의 유형 과next
지침 이 있 습 니 다.그 밖 에 이 노드 가VALUE
유형 이 라면 공간 을 분배 하여 이 노드 의 유효 치 를 저장 해 야 합 니 다.그러나 이 노드 가 SUB 형식 이 라면 포인터 가 서브 시트 의 머리 를 가리 키 는 것 을 정의 해 야 합 니 다.이곳 에서 우 리 는 연합 으로 이 문 제 를 해결 할 수 있다.
(연합(또는 공동체)은 서로 다른 데이터 형식 구성원 간 에 저장 공간 을 공유 하 는 방법 이 고 연합 체 대상 은 같은 시간 에 한 구성원 만 저장 할 수 있다)
구조 노드:
struct GeneralizedNode
{
Type _type; // 1.
GeneralizedNode* _next; //2.
union
{
char _value; // 3.
GeneralizedNode* _subLink; // 3.
};
GeneralizedNode(Type type = HEAD, char value = '0')
:_value(value)
,_type(type)
, _next(NULL)
{
if (_type == SUB)
{
_subLink = NULL;
}
}
};
광의 표 의 정의 및 기본 동작:
class Generalized
{
public:
// ,
Generalized();
// ,
Generalized(const char* str);
//
void Print();
//
size_t Amount();
//
size_t Depth();
//
Generalized(const Generalized& g);
////
Generalized& operator=(const Generalized& g);
////
~Generalized();
protected:
void _Print(GeneralizedNode* head);
GeneralizedNode* _CreatList(const char*& str);
size_t _Amount(GeneralizedNode* head);
GeneralizedNode* _Copy(GeneralizedNode* head);
void _Destory(GeneralizedNode* head);
protected:
GeneralizedNode* _head; //
};
광의 표를 만 들 고 순환 재 귀 를 초기 화 합 니 다.문자열 을 옮 겨 다 닐 때 문 자 를 만나면 값 노드 를 만 들 고'('를 만나면 재 귀적 으로 하위 표를 만 듭 니 다.')'를 만나면 현재 하위 표 의 생 성 을 끝내 고 현재 하위 표 의 머리 지침 을 되 돌려 줍 니 다.
GeneralizedNode* _CreatList(const char*& str)
{
assert(*str == '(');
GeneralizedNode* head = new GeneralizedNode(HEAD,'0');
GeneralizedNode* cur = head;
str++;
while (str != '\0')
{
if ((*str >= '0'&&*str <= '9') || (*str >= 'a'&&*str <= 'z') || (*str >= 'A'&&*str <= 'Z'))
{
cur->_next = new GeneralizedNode(VALUE, *str);
cur = cur->_next;
}
else if (*str == '(')
{
cur->_next = new GeneralizedNode(SUB);
cur = cur->_next;
cur->_subLink = _CreatList(str);
}
else if (*str == ')')
{
return head;
}
str++;
}
return head;
}
인쇄 광의 표:노드 의 유형 이 SUB 일 때 재 귀 합 니 다.마지막 으로 인쇄 가 끝 날 때마다 괄호 를 인쇄 하 는 것 을 잊 지 마 세 요.
void _Print(GeneralizedNode* head)
{
if (head == NULL)
{
cout << "Generalized table is NULL" << endl;
return;
}
GeneralizedNode* cur = head;
while (cur)
{
if (cur->_type == HEAD)
{
cout << '(';
}
else if (cur->_type == VALUE)
{
cout << cur->_value;
if (cur->_next)
{
cout << ',';
}
}
else if (cur->_type == SUB)
{
_Print(cur->_subLink);
if (cur->_next)
{
cout << ',';
}
}
cur = cur->_next;
}
cout << ')';
}
값 노드 의 개수 가 져 오기:count
변 수 를 설정 하고 값 노드 를 만나면 1 을 추가 합 니 다.SUB 노드 를 만나면 재 귀 하고 반환 값 을 추가 합 니 다count
size_t _Amount(GeneralizedNode* head)
{
GeneralizedNode* begin = head;
size_t count = 0;
while (begin)
{
if (begin->_type == VALUE)
{
count++;
}
if (begin->_type == SUB)
{
count += _Amount(begin->_subLink);
}
begin = begin->_next;
}
return count;
}
일반화 표 의 깊이:변수 dp 와 max 를 설정 하여 현재 서브 시트,즉 현재 SUB 노드 가 가리 키 는 서브 시트 의 깊이 와 이 층 의 모든 SUB 노드 에서 깊이 가 가장 큰 서브 시트 의 깊이 를 기록 합 니 다.
size_t _Depth(GeneralizedNode* head)
{
if (_head == NULL)
{
return 0;
}
size_t dp=0;
GeneralizedNode* cur = head;
size_t max = 0;
while (cur)
{
if (cur->_type == SUB)
{
dp=_Depth(cur->_subLink);
if (max < dp)
{
max = dp;
}
}
cur = cur->_next;
}
return max+1;
}
광의 표 삭제:노드 를 순서대로 옮 겨 다 니 며 하위 표 재 귀 를 만 나 하위 표 의 노드 delete 를 완성 한 후 현재 층 으로 돌아 가 계속 옮 겨 다 닙 니 다.
void _Destory(GeneralizedNode* head)
{
if (head == NULL)
{
return;
}
while (head)
{
GeneralizedNode* begin = head->_next;
if (head->_type == SUB)
{
_Destory(head->_subLink);
}
delete head;
head = begin;
}
}
실례 시범정의:
광의 표 는 n(n≥0)개 원소 a1,a2,...,ai,...,an 의 유한 서열 이다.
그 중:
① ai-또는 원자 또는 광의 표.
② 광의 표 는 보통 다음 과 같이 기록한다.
Ls=( a1,a2,…,ai,…,an)。
③ Ls 는 광의 표 의 이름 이 고 n 은 그 길이 이다.
④ ai 가 광의 표 라면 Ls 의 자 표 라 고 부른다.
주의:
① 광의 표 는 괄호 로 묶 고 쉼표 로 그 중의 요 소 를 구분한다.
② 원자 와 광의 표를 구분 하기 위해 서 는 대문자 로 광의 표를 표시 하고 소문 자로 원 자 를 표시 한다.
③ 광의 표 Ls 비 공(n≥1)이 라면 al 은 LS 의 표 두 이 고 나머지 요소 로 구 성 된 표(a1,a2,...,an)는 Ls 의 표 미 라 고 부른다.
④ 광의 표 는 재 귀 정의 이다.
그림 예:
코드 구현:
[cpp] view plain copy
#include <iostream>
using namespace std;
//
enum NodeType
{
HEAD_TYPE,//
VALUE_TYPE,//
SUB_TYPE//
};
//
struct GeneraListNode
{
NodeType _type;//
GeneraListNode *_next;//
// ,
// ,
union{
char _value;
GeneraListNode *_subLink;
};
GeneraListNode(NodeType type = HEAD_TYPE, char value = '\0')
:_type(type)
,_next(NULL)
{
if (type == VALUE_TYPE)
{
_value = value;
}else if(type == SUB_TYPE)
{
_subLink = NULL;
}
}
};
class GeneraList
{
private:
GeneraListNode *_link;//
public:
GeneraList(const char *str)
:_link(NULL)
{
_CreateGeneraList(_link, str);//
}
~GeneraList()
{}
public:
void Print();//
int Size();//
int Depth();//
private:
void _CreateGeneraList(GeneraListNode *& link, const char *& str);
bool _IsValue(const char ch);//
int _Size(GeneraListNode *head);//
int _Depth(GeneraListNode *head);//
void _Print(GeneraListNode *link);//
};
//
void GeneraList::_CreateGeneraList(GeneraListNode *& link, const char *& str)
{
// ,
//
GeneraListNode* head = new GeneraListNode(HEAD_TYPE, NULL);
head->_next = NULL;
link = head;
GeneraListNode* cur = link;//
str++;// , '('
while(*str != '\0')
{
if(_IsValue(*str)){//
//
GeneraListNode* newNode = new GeneraListNode(VALUE_TYPE, *str);
newNode->_next = NULL;
cur->_next = newNode;//
cur = cur->_next;//
str++;//
}else if(*str == '('){// '('
GeneraListNode* subLink = new GeneraListNode(SUB_TYPE, NULL);
subLink->_next = NULL;
cur->_next = subLink;//
cur = cur->_next;
_CreateGeneraList(cur->_subLink, str);//
}else if(*str == ')'){
str++;
return;// ')'
}else{
str++;//
}
}
}
int GeneraList::Size()
{
return _Size(_link);
}
//
int GeneraList::_Size(GeneraListNode *head)
{
int size = 0;
GeneraListNode *cur = head;
while(cur != NULL){
if(cur->_type == VALUE_TYPE){
++size;// size
}else if(cur->_type == SUB_TYPE){
size += _Size(cur->_subLink);//
}
cur = cur->_next;
}
return size;
}
int GeneraList::Depth()
{
return _Depth(_link);
}
int GeneraList::_Depth(GeneraListNode *head)
{
int depth = 1,maxDepth = 1;//depth ,maxDepth
GeneraListNode *cur = head;
while(cur != NULL){
if(cur->_type == SUB_TYPE){
depth += _Depth(cur->_subLink);
}
if(depth > maxDepth){//
maxDepth = depth;
depth = 1;//
}
cur = cur->_next;
}
return maxDepth;
}
void GeneraList::Print()
{
_Print(_link);
cout<<endl;
}
//
void GeneraList::_Print(GeneraListNode *link)
{
GeneraListNode *cur = link;//
while(cur != NULL){
if(cur->_type == VALUE_TYPE){
cout<<cur->_value;
if(cur->_next != NULL)
{
cout<<',';
}
}else if(cur->_type == HEAD_TYPE){
cout<<"(";
}else if(cur->_type == SUB_TYPE){
_Print(cur->_subLink);//
if(cur->_next != NULL)// ','
{
cout<<",";
}
}
cur = cur->_next;
}
cout<<")";
}
bool GeneraList::_IsValue(const char ch)
{
if(ch >= 'a' && ch <= 'z' ||
ch >= 'A' && ch <= 'Z' ||
ch >= '0' && ch <= '(')
{
return true;
}
return false;
}
테스트 코드
[cpp] view plain copy
#include"GeneraList.hpp"
//
void Test1()
{
GeneraList genList("()");
genList.Print();
cout<<"Size is :"<<genList.Size()<<endl;
cout<<"Depth is :"<<genList.Depth()<<endl<<endl;
}
//
void Test2()
{
GeneraList genList("(a,b)");
genList.Print();
cout<<"Size is :"<<genList.Size()<<endl;
cout<<"Depth is :"<<genList.Depth()<<endl<<endl;
}
//
void Test3()
{
GeneraList genList("(a,b,(c,d))");
genList.Print();
cout<<"Size is :"<<genList.Size()<<endl;
cout<<"Depth is :"<<genList.Depth()<<endl<<endl;
}
//
void Test4()
{
GeneraList genList("(a,b,(c,d),(e,(f),h))");
genList.Print();
cout<<"Size is :"<<genList.Size()<<endl;
cout<<"Depth is :"<<genList.Depth()<<endl<<endl;
}
//
void Test5()
{
GeneraList genList("(((),()),())");
genList.Print();
cout<<"Size is :"<<genList.Size()<<endl;
cout<<"Depth is :"<<genList.Depth()<<endl<<endl;
}
int main()
{
Test1();
Test2();
Test3();
Test4();
Test5();
return 0;
}
실행 결과총결산
이상 은 C++광의 표 의 상세 한 설명 을 어떻게 실현 하 는 지 에 관 한 모든 내용 입 니 다.필요 한 사람 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 면 댓 글 을 달 아 토론 하 시기 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Java 프로그램과 C 언어의 차이에 대한 간단한 분석C 언어를 배운 우리에게 자바는 비교적 간단한 프로그래밍 언어라고 할 수 있다. Java 언어에서는 모든 변수를 먼저 선언해야 사용할 수 있습니다. 그렇지 않으면 프로그램이 실행될 수 없습니다.하나의 C 언어는 몇 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.