广义表及其Java代码实现

本文介绍了广义表的概念,其特点是表中的节点可以是原子或广义表,具有递归属性。通过表头hp和表尾tp划分,展示了广义表的构建、求深度和复制的递归方法。提供了一个Java类`GList`,包括创建广义表、获取深度和复制功能的实现,以及辅助方法`sever`用于处理表头和表尾。此外,还提供了一个`Temp`类来辅助处理字符串。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

广义表: 所谓广义表,就是表中的结点可以是"原子",也可以是"广义表".在此我广义表来存储一个字符串(((a,b),(c,d)),(e,(f,g),h),z)
如: 广义表 L = (((a,b),(c,d)),(e,(f,g),h),z); 那么L包含 广义表A=((a,b),(c,d)) , B=(e,(f,g),h)和原子z;依次类推,A也包含其它广义表.

既然如此,那么广义表就有了递归的属性.
我们将广义表的结构分为表头hp和表尾tp两部分.表头为第一个元素,剩余元素为表尾.
L.hp = ((a,b),(c,d)); L.tp = (e,(f,g),h),z; 而L.tp明显也是一个表,所以L.tp.hp = (e,(f,g),h); L.tp.tp = z;

于是光义表的建立,求深度和复制都可以用递归的方法实现.

我们来看 L = (((a,b),(c,d)),(e,(f,g),h),z);用表头,表尾的结构建好的广义表的结构:


可以看到: a,b在同一层; c,d在同一层; e,h在同一层; f,g在同一层。
                而各表尾,以及表尾的表尾。。。。。。在一层。如L.hp=(e,(f,g),h),z和L.hp.hp=(z)在一层。而表头会到下一层。

//广义表,包括广义表的建立,求深度,复制; 采用的是将广义表划分为"头"和"尾"的模式。
//这些操作以"(((a,b),(c,d)),(e,(f,g),h),z)"形式的字符串为基础.一对括号代表一个表.
public class GList {
    //节点类型
    public static int ATOM = 0;
    public static int LIST = 1;
     
     
    public int tag;//用于区分节点
     
    public Object atom;//原子类型
    public GList hp,tp;//指向表头和表尾
     
     
    //建立广义表"(((a,b),(c,d)),(e,(f,g),h),z)"这样形式的字符串为内通建立广义表
    //同样采用递归方式。结束条件是空表和原子。
    //递归建立表头和表尾
    public static GList createGList(GList L,String s){
        System.out.println(s);
        GList p = null; GList q = null;
         
        if(s.equals("()")) L = null;//如果是空表
        else{
            L = new GList();
            if(s.length() == 1){L.tag = ATOM; L.atom = s.charAt(0);}//创建单原子广义表
            else{
                 L.tag = LIST; p = L;
                 String sub = s.substring(1,s.length()-1);
                  
                 do{//小尾中脱出头,循环建立同一层次的结点
                     Temp temp = new Temp(sub);
                     String hsub = sever(temp);
                     sub = temp.string;
                      
                     p.hp = createGList(p.hp,hsub); q= p;//hsub是头建立头
                      
                     if(!sub.isEmpty()){//如果有尾
                         p = new GList();
                         p.tag = LIST; 
                         q.tp = p;
                     }
                 }while(!sub.isEmpty());
                 q.tp = null;
            }
        }
         
        return L;
    }
 
 
    //该函数处理(((a,b),(c,d)),(e,(f,g),h),z)后,hstr = ((a,b),(c,d)) str = (e,(f,g),h),z.
//等于把表头和表尾分开
    public  static String sever(Temp t) {
        String str = t.string;
        int n = str.length(); int i=0;int k=0;
        char ch;
        String hstr = null;
         
        do{
            ch = str.charAt(i);
            i++;
             
            if(ch == '(') k++;
            else if(ch == ')') k--;
        }while(i<n && (ch !=',' || k!=0));
         
        if(i<n){
            hstr = str.substring(0,i-1);
            str = str.substring(i);
        }else{
            hstr = str; str = "";
        }
         
        t.string = str;
        return hstr;
    }
     
    //求广义表的深度
    public static int GetDeepth(GList L){
        if(L == null) return 1;//空表
        if(L.tag == ATOM) return 0;//原子
        int  max = 0;  GList p = L;
        for(;p!=null;p=p.tp){//求同一层的光仪表元素的最大深度
            int tem = GetDeepth(p.hp);
            if(tem > max) max = tem;
        }
         
        return max+1;
    }
     
    //复制广义表
    public static GList Copy(GList M,GList L){//复制广义表,把L复制到M
        if(L == null) M = null;//空表
        else{
            M = new GList();
            M.tag = L.tag;
            if(M.tag == ATOM) M.atom = L.atom;
            else{
                M.hp = Copy(M.hp, L.hp);//复制头
                M.tp = Copy(M.tp,L.tp);//复制尾
            }
        }
        return M;
    }
     
    public static void main(String[] args){
        GList L = null;
        String s = "(((a,b),(c,d)),(e,(f,g),h),z)";
         
        //建表
        L = GList.createGList(L, s);
        //求表深度
        int len = GList.GetDeepth(L);
        System.out.println(len);
        //表复制
        GList M = null;
        M = GList.Copy(M, L);
    }
}
 
//为了应对值传递,只能传递引用拷贝,无法传递“地址”的问题
class Temp{
    String string = "";
    public Temp(String s){
        string = s;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值