zoukankan      html  css  js  c++  java
  • DS博客作业02--栈和队列

    0.PTA得分截图

    1.本周学习总结

    1.1 总结栈和队列内容

    一.栈:

    栈是一种只能在栈顶一端进行插入或删除操作的线性表。
    栈中元素遵循先进后出的规则。元素未完全进栈时即可出栈

    栈的存储结构:

    1.顺序栈:

    • 顺序栈结构体定义:
    typedef struct 
    {  ElemType data[MaxSize]; //栈中数据元素
       int top;		//top为栈顶指针
    } Stack;
    typedef Stack *SqStack;
    
    
    • 顺序栈四大要素:
      1.栈空条件:top=-1
      2.栈满条件:top=MaxSize-1
      3.进栈e操作:top++; st->data[top]=e
      4.退栈操作:e=st->data[top]; top--;

    • 顺序栈基本操作

    1.初始化栈:

    void CreateStack(SqStack& s)
    {
    	s = new Stack;
    	s->top = -1;
    }
    

    2.判断栈空:

    int EmptyStack(SqStack s)
    {
    	if (s->top == -1)
    		return 1;
    	else
    		return 0;
    }
    

    3.判断栈满:

    int FullStack(SqStack s)
    {
    	if (s->top == MaxSize-1)
    		return 1;
    	else
    		return 0;
    }
    

    4.元素入栈:

    bool Push(SqStack& s, ElemType e)
    {
    	if (s->top == MaxSize - 1)
    		cout << "FULLSTACK";
    		return false;
    	s->top++;		   //栈顶指针增1
    	s->data[s->top] = e;
    	return true;
    }
    
    

    5.元素出栈:

    bool Pop(SqStack &s,ElemType &e)
    {
       if (s->top==-1)	//栈空的情况
    	return false;
       e=s->data[s->top];   
       s->top--;
       return true;
    }
    
    

    6.取栈顶:

    bool GetTop(SqStack *s,ElemType &e)
    {	
       if (s->top==-1)	//判断栈空 
        return false;
        e=s->data[s->top];//栈顶元素赋值为e
        return true;
    }
    
    

    7.销毁栈:

    void ClearStack(SqStack& s)
    {
    	delete s;
    }
    

    8.共享栈:

    *共享栈类型定义:

    typedef struct
    {     ElemType data[MaxSize];	//存放共享栈中元素
           int top1,top2;		//两个栈的栈顶指针
    } DStack;	
    
    

    *共享栈结构体定义:

    struct SNode {
        ElementType *Data;
        Position Top1, Top2;
        int MaxSize;
    };
    typedef struct SNode *Stack;
    
    

    *共享栈三要素:
    1.栈1空:top1-1
    2.栈2空:top2
    MaxSize
    3.栈满:top1+1=top2

    2.链式栈(带头节点):

    • 链式栈的结构体定义:
    typedef struct linknode
    {  ElemType data;			//数据域
       struct linknode *next;	//指针域
    } LiNode,*LiStack;
    
    
    • 链式栈四大要素:
      1.栈空条件:s->next=NULL
      2.栈满条件:不考虑
      3.进栈e操作:结点插入到头结点后,链表头插法
      4.退栈操作:取出头结点之后结点的元素并删除

    • 链式栈基本操作:

    1.初始化栈:

    void InitStack(LiStack &s)
    {  s=new LiNode;
       s->next=NULL;
    }
    
    

    2.判断栈空:

    int StackEmpty(LiStack s)
    {
    	if (s->next == NULL)
    		return 1;
    	else
    		return 0;
    }
    

    3.元素入栈:

    void Push(LiStack& s, ElemType e)
    {
    	LiStack p;
    	p = new LiNode;
    	p->data = e;		//新建节点p
    	p->next = s->next;	//插入*p节点作为开始节点
    	s->next = p;
    }
    
    

    4.元素出栈:

    bool Pop(LiStack& s, ElemType& e)
    {
    	LiStack p;
    	if (s->next == NULL)		//栈空的情况
    		return false;
    	p = s->next;			//p指向开始节点,从栈顶开始出栈
    	e = p->data;
    	s->next = p->next;		//删除*p节点
    	free(p);				//释放*p节点
    	return true;
    }
    
    

    5.取栈顶元素:

    bool GetTop(LiStack s,ElemType &e)
    {  if (s->next==NULL)	//栈空的情况
    	return false;
       e=s->next->data;
       return true;
    }
    
    

    6.销毁栈:

    void DestroyStack(LiStack &s)
    { LiStack p;
       while (s!=NULL)
       {   p=s; 	
           s=s->next;
           free(p); 
       }
     }
    
    

    栈的应用:

    C++模板类:stack类

    1.stack s:初始化栈,参数表示元素类型
    2.s.push(t):入栈元素t
    3.s.top():返回栈顶元素
    4.s.pop():出栈操作只是删除栈顶元素(彻底删除),并不返回该元素。
    5.s1.empty(),当栈空时,返回true。
    6.s1.size():访问栈中的元素个数

    栈的应用

    1.中缀表达式转后缀表达式(符号简化)

    while (从exp读取字符ch,ch!='')
    {       ch为数字:将后续的所有数字均依次存放到postexp中,
                         并以字符'#'标志数值串结束;
            ch为左括号'(':将此括号进栈到Optr中;
            ch为右括号')':将Optr中出栈时遇到的第一个左括号'('以前的运算符
                        依次出栈并存放到postexp中,然后将左括号'('出栈;
            ch为'+'或'-':
                       出栈运算符并存放到postexp中,直到栈空或者栈顶为'(',
                       然后将'+'或'-'进栈;
            ch为'*'或'/':
                          若 栈顶为'*'或'/',出栈,直到栈顶不是'*'或'/'
                          否则 入栈
    }
    若exp扫描完毕,则将Optr中所有运算符依次出栈并存放到postexp中。
    
    

    2.后缀表达式求值:

    while (从postexp读取字符ch,ch!='')
    {    若ch为数字,将后续所有数字构成一个整数存放数值栈st中。
         若ch为“+”,则从数值栈st中退栈两个运数,相加后进栈st中。
         若ch为“-”,则从数值栈st中退栈两个数,相减后进栈st中。
         若ch为“*”,则从数值栈st中退栈两个数,相乘后进栈st中。
         若ch为“/”,则从数值栈st中退栈两个数,相除后进栈st中
            (若除数为零,则提示相应的错误信息)。}
    若字符串postexp扫描完毕,则数值栈op中的栈顶元素就是表达式的值。
    
    

    3.迷宫问题:

    初始化栈st,入口方块(x1,y1)入栈
    //可走方位左3右1,上0下2;  bi
    //方块(x,y)->(i,j)行号和列号
    while 栈不为空
    	遍历取栈顶
    	if 栈顶是出口
    		输出栈中内容
    	end if
    	bi初始化为-1;
    	while 未走遍相邻方块且未找到可行下一步
    		bi++;
    		if bi为0  向上走;
    		else if bi为1 向右走;
    		else if bi为2 向下走;
    		else bi为3 向左走;
    		end if
    	end while
    	if 方块可行
    		记录寻找可行方块的路径存入栈中
    	else 退栈返回上一个位置并将现方块列为可行方块
    	end if
    end while
    

    二.队列:

    队列是只允许在表的一端进行插入,而在表的另一端进行删除的线性表。
    队列中元素遵循先进先出的原则

    队列的存储结构:

    1.顺序队列:

    • 顺序队列结构体定义:
    typedef struct 
    {     ElemType data[MaxSize]; 
          int front,rear;      //队首和队尾指针
    }Queue;
    typedef Queue *SqQueue;
    
    
    • 顺序队列四大要素:
      1.队空条件:front = rear(初始时front = rear=-1)
      2.队满条件:rear=MaxSize-1
      3.元素e进队:rear++;data[rear]=e;
      4.元素e出队:front++;e=data[front];

    • 顺序队列基本操作

    1.初始化顺序队列:

    void InitQueue(SqQueue &q)
    {	q=new Queue;
    	q->front=q->rear=-1;
    }
    
    

    2.判断队列是否为空:

    bool QueueEmpty(SqQueue q)
    {
       return(q->front==q->rear);
    }
    
    

    3.判断队列是否为满:

    bool QueueFULL(SqQueue q)
    {
       return(q->rear==MaxSize-1);
    }
    

    4.进队列:

    bool enQueue(SqQueue &q,ElemType e)
    {  
        if (q->rear+1==MaxSize)	   return false;
                                           //队满上溢出
    	q->rear=q->rear+1;
    	q->data[q->rear]=e;
    	return true;
    }
    
    

    5.出队列:

    bool deQueue(SqQueue &q,ElemType &e)
    {	
             if (q->front==q->rear)  //队空下溢出
    		return false;
    	q->front=q->front+1;
    	e=q->data[q->front];
    	return true;
    }
    
    

    6.销毁队列:

    void DestroyQueue(SqQueue &q)
    {
      delete q;
    }
    
    
    • 为了解决队列元素假溢出的问题,我们引进循环队列的做法:
    循环队列:

    把数组的前端和后端连接起来,形成一个环形的顺序表,即把存储队列元素的表从逻辑上看成一个环,称为环形队列或循环队列。

    • 循环队列结构体定义
    typedef struct 
    {	
      ElemType data[MaxSize];
      int front,rear;	
    } Queue;
    typedef Queue *SqQueue;
    
    • 循环队列两要素:
      1.队空:frontrear
      2.队满:(rear+1)%M
      front

    • 循环队列基本操作

    1.初始化队列:

    void InitQueue(SqQueue &q)
    {   q=new Queue;
        q->front=q->rear=0;
    }
    
    

    2.判断队列是否为空:

    bool QueueEmpty(SqQueue q)
    {
    	return(q->front==q->rear);
    }
    
    

    3.判断队列是否为满:

    bool QueueFULL(SqQueue q)
    {
    	return((q->rear+1)%MaxSize==q->front);
    }
    

    4.入队列:

    bool enQueue(SqQueue &q,ElemType e)
    {	if ((q->rear+1)%MaxSize==q->front)	//队满上溢出
    		return false;
    	q->rear=(q->rear+1)%MaxSize;
    	q->data[q->rear]=e;
    	return true;
    }
    
    

    5.出队列:

    bool deQueue(SqQueue &q,ElemType &e)
    {	if (q->front==q->rear)		//队空下溢出
    		return false;
    	q->front=(q->front+1)%MaxSize;
    	e=q->data[q->front];
    	return true;
    }
    

    6.销毁队列:

    void DestroyQueue(SqQueue &q)
    {
    	delete q;
    }
    
    

    7.求循环队列长度:

    int  QueueLength (SqQueue Q)
    {
         return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;                   
    }
    
    
    链式队列:

    • 链式队列结构体定义:
    typedef struct QNode{
       QElemType   data;
       struct Qnode  *next;
    }Qnode, *QueuePtr;//定义节点类型
    typedef struct {
       QueuePtr  front;            //队头指针   
       QueuePtr  rear;             //队尾指针
    }LinkQueue;  //定义队列类型
    
    
    • 链队列四要素:
      1.队空条件:front=rear
      2.队满条件:不考虑
      3.进队e操作:将包含e的节点插入到单链表表尾
      4.出队操作:删除单链表首数据节点

    • 链队列基本操作:

    1.初始化队列:

    Status InitQueue (LinkQueue &Q)
    {
       Q.front=Q.rear=new QNode; 
        if(!Q.front) exit(OVERFLOW);
        Q.front->next=NULL;
         return OK;
    }
    
    

    2.判断队列是否为空:

    Status QueueEmpty(LinkQueue Q)
    {
    	return (Q.front == Q.rear);
    }
    
    

    3.入队:

    Status EnQueue(LinkQueue& Q, QElemType e)
    {
    	p = (QueuePtr)malloc(sizeof(QNode));
    	if (!p) exit(OVERFLOW);
    	p->data = e; p->next = NULL;
    	Q.rear->next = p;
    	Q.rear = p;
    	return OK;
    }
    
    
    

    4.出队:

    Status DeQueue(LinkQueue& Q, QElemType& e)
    {
    	if (Q.front == Q.rear) return ERROR;
    	p = Q.front->next;
    	e = p->data;
    	Q.front->next = p->next;
    	if (Q.rear == p) Q.rear = Q.front;
    	delete p;
    	return OK;
    }
    
    

    5.取链队列的队头元素:

    Status GetHead(LinkQueue Q, QElemType& e) 
    {
    	if (Q.front == Q.rear) return ERROR;
    	e = Q.front->next->data;
    	return OK;
    }
    

    6.销毁队列:

    Status DestroyQueue(LinkQueue& Q)
    {
    	while (Q.front)
    	{
    		Q.rear = Q.front->next;
    		free(Q.front);
    		Q.front = Q.rear;
    	}
    	return OK;
    }
    
    

    队列的应用:

    C++容器:queue

    q1.push(x): 将x接到队列的末端。
    q1.pop():弹出队列的第一个元素,并不会返回被弹出元素的值。(front后移时队列中元素并未完全消失)
    q1.front():即最早被压入队列的元素。
    q1.back():即最后被压入队列的元素。
    q1.empty():当队列空时,返回true。
    q1.size():访问队列中的元素个数

    队列的应用:

    1.舞伴问题:

    
    int QueueLen(SqQueue Q)//队列长度 
    {
    	因为是顺序队列,所以队列长度为队尾减队首
    	返回Q->rear - Q->front;
    }
    int EnQueue(SqQueue& Q, Person e)//加入队列 
    {
    	if 队满
    	返回0
    	else
    	元素e入队,队尾后移
    }
    int QueueEmpty(SqQueue& Q)//队列是否为空 
    {
    	直接返回队首队尾相等比较的结果
    	return Q->front == Q->rear;
    }
    int DeQueue(SqQueue& Q, Person& e)//出队列 
    {
    	if 队空
    	返回0
    	else
    	元素e出队,队首后移
    }
    void DancePartner(Person dancer[], int num) //配对舞伴 
    {
    	int k;
    	Person e;
    	for k = 0 to k=num-1
    		if 字符数组元素为男
    			元素入Fdancers队
    		else 字符数组元素为女
    			元素入Mdancers队
    		end if
    	end for
    	while 男队女队都不空
    		输出男女配对舞伴
    	end while
    }
    

    2.迷宫问题:

    #include <stdio.h>
    #define MaxSize 100
    #define M 8
    #define N 8
    int mg[M+2][N+2]=
    {	
    	{1,1,1,1,1,1,1,1,1,1},
    	{1,0,0,1,0,0,0,1,0,1},
    	{1,0,0,1,0,0,0,1,0,1},
    	{1,0,0,0,0,1,1,0,0,1},
    	{1,0,1,1,1,0,0,0,0,1},
    	{1,0,0,0,1,0,0,0,0,1},
    	{1,0,1,0,0,0,1,0,0,1},
    	{1,0,1,1,1,0,1,1,0,1},
    	{1,1,0,0,0,0,0,0,0,1},
    	{1,1,1,1,1,1,1,1,1,1}
    };
    typedef struct 
    {	int i,j;			//方块的位置
    	int pre;			//本路径中上一方块在队列中的下标
    } Box;					//方块类型
    typedef struct
    {
    	Box data[MaxSize];
    	int front,rear;		//队头指针和队尾指针
    } QuType;				//定义顺序队类型
    void print(QuType qu,int front)	//从队列qu中输出路径
    {
    	int k=front,j,ns=0;
    	printf("
    ");
    	do				//反向找到最短路径,将该路径上的方块的pre成员设置成-1
    	{	j=k;
    		k=qu.data[k].pre;
    		qu.data[j].pre=-1;
    	} while (k!=0);
    	printf("迷宫路径如下:
    ");
    	k=0;
    	while (k<MaxSize)  //正向搜索到pre为-1的方块,即构成正向的路径
    	{	if (qu.data[k].pre==-1)
    		{	ns++;
    			printf("	(%d,%d)",qu.data[k].i,qu.data[k].j);
    			if (ns%5==0) printf("
    ");	//每输出每5个方块后换一行
    		}
    		k++;
    	}
    	printf("
    ");
    }
    int mgpath(int xi,int yi,int xe,int ye)					//搜索路径为:(xi,yi)->(xe,ye)
    {
    	int i,j,find=0,di;
    	QuType qu;						//定义顺序队
    	qu.front=qu.rear=-1;
    	qu.rear++;
    	qu.data[qu.rear].i=xi; qu.data[qu.rear].j=yi;	//(xi,yi)进队
    	qu.data[qu.rear].pre=-1;	
    	mg[xi][yi]=-1;					//将其赋值-1,以避免回过来重复搜索
    	while (qu.front!=qu.rear && !find)	//队列不为空且未找到路径时循环
    	{	
    		qu.front++;					//出队,由于不是环形队列,该出队元素仍在队列中
    		i=qu.data[qu.front].i; j=qu.data[qu.front].j;
    		if (i==xe && j==ye)			//找到了出口,输出路径
    		{	
    			find=1;				
    			print(qu,qu.front);			//调用print函数输出路径
    			return(1);				//找到一条路径时返回1
    		}
    		for (di=0;di<4;di++)		//循环扫描每个方位,把每个可走的方块插入队列中
    		{	
    			switch(di)
    			{
    			case 0:i=qu.data[qu.front].i-1; j=qu.data[qu.front].j;break;
    			case 1:i=qu.data[qu.front].i; j=qu.data[qu.front].j+1;break;
    			case 2:i=qu.data[qu.front].i+1; j=qu.data[qu.front].j;break;
    			case 3:i=qu.data[qu.front].i, j=qu.data[qu.front].j-1;break;
    			}
    			if (mg[i][j]==0)
    			{	qu.rear++;				//将该相邻方块插入到队列中
    				qu.data[qu.rear].i=i; qu.data[qu.rear].j=j;
    				qu.data[qu.rear].pre=qu.front; //指向路径中上一个方块的下标
    				mg[i][j]=-1;		//将其赋值-1,以避免回过来重复搜索
    			}
    		}
         }
         return(0);						//未找到一条路径时返回1
    }
    int main()
    {
    	mgpath(1,1,M,N);
    	return 1;
    }
    
    

    3.报数问题:

    数据结构:
    结构体定义:
    int型在队首元素前一位的front;
    int型队尾rear;
    整型数组Data[最大队列容量MaxSize];
    顺序队列Queue;
    创建新队列,数据入队
    while 队列不为空
    //此时front在-1的位置
    	while 遍历队列
    		//取出输出队首,front后移一位
    		cout << Queue->data[front + 1] << " ";
    		front++;
    		//取出偶数位置的数字再入队放在最后
    		e = Queue->data[front + 1];
    		rear++;
    		Queue->data[rear]=e;
    	end while
    end while
    

    1.2.谈谈你对栈和队列的认识及学习体会。

    队列
    先进后出 先进先出
    出栈元素在栈中完全删除 出队元素在队中不完全删除
    只能在一端插入删除 在队头删除队尾插入
    线性结构 线性结构
    插入删除时间复杂度O(1) 插入删除时间复杂度O(1)

    栈和队列虽然原理不同,但都是线性结构存储数据的一种特殊计算方法,为表达式转换等问题提供了简便的做法。在学习栈和队列的过程中,用C++容器真的带给了我巨大的便利,在做题的时候感觉理解题意很难,有挺多测试点过不去,还是要拜托对搜索引擎的依赖,反思自己为什么不会做相对缜密的题。

    2.PTA实验作业

    2.1.题目1:7-7 银行业务队列简单模拟

    2.1.1代码截图



    2.1.2本题PTA提交列表说明。

    Q1:在队列A判断完又进行了一次flag初始化
    A1:在开始flag初始化一次即可
    Q2:队列B没有判断空格的问题,忘记了顾客编号都为偶数的情况
    A2:在队列B中也进行数字后空格的判断,防止有顾客编号都为偶数的情况出现。
    

    2.2.题目2:6-5 jmu-ds-舞伴问题

    2.2.1代码截图



    2.2.2本题PTA提交列表说明。

    Q1:计算队列长度时把队列当成可变的了
    A1:用固定队列队尾减队首就可以求出队列长度了
    Q2:在最后输出配对舞伴时两人之间的空格数搞错了
    A2:把输出一个空格改为输出两个空格
    

    3.阅读代码

    3.1 题目及解题代码

    题目:来源:力扣(LeetCode)

    解题代码:

    public class Solution {
        public boolean find132pattern(int[] nums) {
            if (nums.length < 3)
                return false;
            Stack < Integer > stack = new Stack < > ();
            int[] min = new int[nums.length];
            min[0] = nums[0];
            for (int i = 1; i < nums.length; i++)
                min[i] = Math.min(min[i - 1], nums[i]);
            for (int j = nums.length - 1; j >= 0; j--) {
                if (nums[j] > min[j]) {
                    while (!stack.isEmpty() && stack.peek() <= min[j])
                        stack.pop();
                    if (!stack.isEmpty() && stack.peek() < nums[j])
                        return true;
                    stack.push(nums[j]);
                }
            }
            return false;
        }
    }
    
    

    3.1.1 该题的设计思路










    时间复杂度:O(N)
    空间复杂度:O(N)
    

    3.1.2 该题的伪代码

    public class Solution {
    	public boolean find132pattern(int[] nums) {
    		if 数组元素少于3个
    			return false;
    		end if
    		Stack < Integer > stack = new Stack < >();//定义栈
    		定义最小数数组min[]来储存啊a[i]
    		min[0] = nums[0];//min数组初始化
    		for i = 1 to nums.length-1
    			min[i] = Math.min(min[i - 1], nums[i]);//求j点左侧最小的a[i]
    		end for
    		for j = nums.length - 1 to 0
    			if a[j]大于最小a[i]
    				while 栈非空且栈顶元素小于a[i]
    					栈顶出栈
    				end while
    				if 栈非空且栈顶元素小于a[j]
    					return true;
    				end if
    				a[j]入栈
    			end if
    		end for
    		return false;
    	}
    }
    
    

    3.1.3 运行结果

    3.1.4 该题目解题优势及难点。

    *优势:
    分部进行比较,先比较a[i]<a[j],先假设定义一个j,寻找j左侧最小的a[i];寻找到最优a[i]后从队尾到a[j]寻找a[k],将所有a[k]放入栈中让它成栈底最大栈顶最小的倒序,a[k]<a[j]的栈顶不合理,pop出栈,寻找到a[k]>a[i],再去比较a[k]<a[j],如果可以匹配就说明有“132”模式的子序列。
    
    *难点:
    a[j]的比较寻找,因为j是不确定的,只能边移边找,分部比较也挺难理解;
    
    

    3.2 题目及解题代码

    题目:来源:力扣(LeetCode)

    解题代码:

    class CQueue {
        Stack<Integer> stack1;
        Stack<Integer> stack2;
        int size;
    
        public CQueue() {
            stack1 = new Stack<Integer>();
            stack2 = new Stack<Integer>();
            size = 0;
        }
        
        public void appendTail(int value) {
            while (!stack1.isEmpty()) {
                stack2.push(stack1.pop());
            }
            stack1.push(value);
            while (!stack2.isEmpty()) {
                stack1.push(stack2.pop());
            }
            size++;
        }
        
        public int deleteHead() {
            if (size == 0) {
                return -1;
            }
            size--;
            return stack1.pop();
        }
    }
    
    

    3.2.1 该题的设计思路

    插入元素:
    时间复杂度:O(n)。插入元素时,对于已有元素,每个元素都要弹出栈两次,压入栈两次,因此是线性时间复杂度。
    空间复杂度:O(n)。需要使用额外的空间存储已有元素。
    
    删除元素:
    时间复杂度:O(1)。判断元素个数和删除队列头部元素都使用常数时间。
    空间复杂度:O(1)。从第一个栈弹出一个元素,使用常数空间。
    
    

    3.2.2 该题的伪代码

    class CQueue {
    	Stack<Integer> stack1;//第一个栈
    	Stack<Integer> stack2;//辅助栈
    	int size;//队列元素数
    
    	public CQueue() {
    		stack1初始化 
    		stack2初始化
    		size = 0;//队列元素数开始为0
    	}
    
    	public void appendTail(int value) {
    		while stack1不为空
    			将stack1中新插入的元素push进stack2中
    		end while
    		新元素value入栈stack1
    		while stack2非空
    			将stack2中的元素再全部返回stack1中
    		end while
    		size++;
    	}
    
    	public int deleteHead() {
    		if 队列为空 
    			return -1;
    		end if
    		队列元素-1
    		return stack1.pop();
    	}
    }
    

    3.2.3 运行结果

    3.2.4 该题目解题优势及难点

    *优势:
    它是用第一个栈来储存新插入的元素,然后将第一个栈中的元素放入第二个栈中,最后把第二个栈中的元素全部返回到第一个栈中,使新插入的元素成为栈底,其他的元素顺序和输入的时候相同,符合队列的规则。
    
    *难点:
    第二个栈给第一个栈做辅助栈,两个栈之间的元素倒换很麻烦。
    
  • 相关阅读:
    关系数据模型和对象数据模型之间的对应关系
    object中的方法
    重写与重载
    java中的多态总结
    int是java.lang包中可用的类的名称
    abstract关键字的说法
    7迭代器
    6python *args **kwargs
    1特征工程
    1html
  • 原文地址:https://www.cnblogs.com/zyc01-jm/p/12548125.html
Copyright © 2011-2022 走看看