• 共享结构的库存模型实现



    见代码



    #define OVERFLOW -2
    
    typedef enum{ATOM,LIST}ElemTag; //ATOM=0,原子;LIST=1,子表;
    
    typedef char *AtomType;        //原子类型
    
    typedef struct GLNode{
    	ElemTag tag;               //公共部分,区别原子结点和表结点
    	union {
    		AtomType atom;         //原子结点的值域
    		struct{struct GLNode *hp,*tp;
    		       char *listname;
    		}ptr;                  //分指表头和表尾
    	};
    }*GList;                       //广义表类型
    
    /********************字符串的操作***********************************/
    int StrLength(char *s)           //返回串长
    {return strlen(s);
    }
    
    status SubString(char *&sub,char *str,int pos,int len)
    //取出从pos位置起,长为len的子串
    {char *p;  
     int k,i;
     p=str;k=StrLength(str);
     if(pos<1||pos>k||len<0||len>k-pos+1) return ERROR;  //参数不合法
     sub=new char[len+1];
     for(i=pos-1;i<pos+len-1;i++) 
    	 *sub++=*(p+i);
     *sub='\0';
     sub=sub-len;
     return OK;
    }
    
    void StrCopy(char *&t,char *s)//将子串s复制到t
    { t=new char[StrLength(s)+1];
      strcpy(t,s);
    }
    
    int StrCompare(char *s,char *t)  //比较串s和t
    { return strcmp(s,t);
    }
    
    status StrEmpty(char *s) //判断串s是否为空
    {
      if(!s) return OK;   //若空返回OK
      else return ERROR;   //否则返回ERROR
    }
    
    void ClearString(char *&s)  //清空串s
    { if(s){
    	delete(s);
        s=NULL;
      }
    }
    
    /********************出错信息处理***********************************/
    void ERRORMESSAGE(char *s)    //出错信息处理函数
    {
     cout<<s<<endl;
     exit(1);
    }
    
    /***********************建广义表********************************/
    void Sever(char *&sub,char *&str){//分离出表头或原子结点的字符串
    	int i=1,n;char *ch;
    
    	n=StrLength(str);
    	SubString(ch,str,i,1);   
    	if(*ch=='('){      //若第一个字符为(,则或为空表,或为共享部分,返回(
    		sub=ch;
    		SubString(str,str,2,n-1); //str为剩余部分
    	}
    	else{               //否则返回表头或原子结点的字符串
    		while(*ch!=')'&&*ch!=','&&*ch!='('&&*ch!='\0') {
    			i++;
    		SubString(ch,str,i,1);   
    		}
    	    SubString(sub,str,1,i-1);
    		SubString(str,str,i,n-i+1);//str为剩余部分
    	}
    }
    
    status GetChar(char *&str,char &ch){ //从字符串头分离一个字符
    	int n; 
    	if(!str) return ERROR;
    	n=StrLength(str);
    	ch=*str;                     //取出第一个字符  
    	SubString(str,str,2,n-1);    //str为剩余部分
    	return OK;
    }
    
    status CreatGList(GList &L,char *&s){  //创建带子表名的广义表
    	char *ch1,ch2,ch; GList p;status i;
    	Sever(ch1,s);                     //取字符串
        GetChar(s,ch2);                    //取下一个字符
    	if((*ch1=='('||*ch1=='#')&&ch2==')'){ //空表或共享表部分
    		L=NULL;
    		if(*ch1=='('){
    	        GetChar(s,ch);         //读取下一字符以判断是否仍有未建子表
    		    if(ch==',') return 1;  //仍有未建子表返回1
    		    else return 2;         //此层次上的子表建完,返回2
    		}
    		else return 2; 
    	}
    	if(!(L=new GLNode)) exit(OVERFLOW);
    	if(ch2==','||ch2==')'||ch2=='\0'){ //原子结点
    		L->tag=ATOM;L->atom=ch1;
    		if(ch2==',') return 1;         //仍有未建子表返回1
    		else return 2;                 //此层次上的子表建完,返回2
    	}
    	if(ch2=='('){                 //表结点
    		L->tag=LIST;
    		L->ptr.listname=ch1;      //listname存放表名
    		i=CreatGList(L->ptr.hp,s);
    		p=L;
    		while(i!=2){              //i!=2时递归建下一子表
    			p=p->ptr.tp=new GLNode;
    			p->tag=LIST;p->ptr.listname="#";
    			i=CreatGList(p->ptr.hp,s);
    		}
    		p->ptr.tp=NULL;
    	    GetChar(s,ch);
    		if(ch==',') return 1;       //仍有未建子表返回1
    		else return 2;              //此层次上的子表建完,返回2
    	}
        return FALSE;                   //字符串错误
    }//Creat
    
    /*********************广义表共享*********************************/
    GList Get(GList L,int I[])  //根据层次序号查找共享及被共享结点
    { int k,j;   GList p;
      k=0; p=L;
      while(I[k]){
    	  j=1;
    	  while(j<I[k]) {p=p->ptr.tp;j++;}//根据层次序号的第一个数向表尾部走
    	  k++;
    	  if(I[k]) p=p->ptr.hp;           //向表头部走
      } 
      return p;
    }
    
    void Share(GList &L)            //建立共享结构
    {   GList p,q;
    	int I[10];int i; char ch;
    	do{ i=0; 
    		cout<<"共享子表序号:"<<endl;
    	    cin>>I[i];
    	    while(I[i]) cin>>I[++i];
    	    p=Get(L,I);              //p指向共享子表
    		i=0;
            cout<<"被共享子表序号:"<<endl;
            cin>>I[i];
    	    while(I[i]) cin>>I[++i];
            q=Get(L,I);              //q指向被共享子表
    	    p->ptr.hp=q->ptr.hp;p->ptr.tp=q->ptr.tp;  //共享
    		cout<<"another?(y/n)";   //若还有其余共享,输入y
    		cin>>ch;
    	}while(ch=='Y'||ch=='y');   //循环控制共享结点个数
    } 
    
    /***********************打印广义表*****************************/
    status PrintGList(GList L,int i)//打印广义表,i为空格数,初始为0
    { GList p,q;int k;
      if(!L) {
    	  for(k=0;k<i;k++) cout<<' ';
          cout<<"#"<<endl; return OK;
      }                                    //打印空表
      if(L->tag==ATOM) {
    	  for(k=0;k<i;k++) cout<<' ';
    	  cout<<L->atom<<endl; return OK;
      }                                    //打印原子结点
      p=L;
      for(k=0;k<i;k++) cout<<' ';
      cout<<p->ptr.listname<<endl;         //打印子表名
      while(p){                            //打印各个子表
    	  q=p->ptr.hp;                     //q指向第一个子表
    	  PrintGList(q,i+2);               //递归打印第一个子表,空格数增加
    	  p=p->ptr.tp;                     //指针后移
      }//while
      return OK;
    }//PrintGList


  • 相关阅读:
    关于EasyUI datagrid 无法在dialog中显示的问题分析及解决方案!
    WPF 矩形框8个控制点伸缩及拖拽
    Socket异步通信及心跳包同时响应逻辑分析(最后附Demo)。
    C#断点续传下载。
    C# 全屏坐标及区域坐标获取。自定义光标及系统光标描边捕捉显示。
    解决项目无法添加VBIDE问题
    python爬虫-入门-了解爬虫
    字符串输入数字
    面试题3--数组中的重复数字(new数组的新写法)
    等号操作符重载为什么不能用友元函数大揭秘,以及函数没有等到重载的时候赋值会出现什么现象(盲点)
  • 原文地址:https://www.cnblogs.com/new0801/p/6177606.html
Copyright © 2020-2023  润新知