初阶数据结构——栈和队列习题

news2024/11/25 16:20:12

目录

    • 括号匹配问题
      • 思路
      • 代码
    • 用队列实现栈
      • 思路
      • 注意点
      • 代码
    • 用栈实现队列
      • 思路
      • 代码
    • 设计循环队列
      • 思路
      • 数组实现代码
      • 链表实现代码

括号匹配问题

OJ链接
在这里插入图片描述

思路

是左括号则入栈,是右括号则出栈然后两两比较
在这里插入图片描述

代码

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
#include<string.h>

typedef char STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;

void STInit(ST* pst);
void STDestroy(ST* pst);
void STPush(ST* pst,STDataType x);
void STPop(ST* pst);
STDataType STTop(ST* pst);
bool STEmpty(ST* pst);
int STSize(ST* pst);

void STInit(ST* pst)
{
	assert(pst);
	pst->a = NULL;
	pst->top = 0;//top指向栈顶元素的下一个位置
	pst->capacity = 0;
}

void STDestroy(ST* pst)
{
	assert(pst);
	free(pst->a);
	pst->a = NULL;
	pst->capacity = pst->top = 0;
}

void STPush(ST* pst, STDataType x)
{
	assert(pst);
	if (pst->top == pst->capacity)
	{
		int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(pst->a, newcapacity*sizeof(STDataType));
		if (tmp == NULL)
		{
			//printf("error: %s\n", strerror(errno));
            perror("realloc fail\n");
			return;
		}
		pst->a = tmp;
		pst->capacity = newcapacity;
	}
	pst->a[pst->top++] = x;
}

void STPop(ST* pst)
{
	assert(pst);
	assert(!STEmpty(pst));
	pst->top--;
}

STDataType STTop(ST* pst)
{
	assert(pst);
	assert(!STEmpty(pst));
	return pst->a[pst->top - 1];
}

bool STEmpty(ST* pst)
{
	assert(pst);
	return pst->top == 0;
}

int STSize(ST* pst)
{
	assert(pst);
	return pst->top;
}

bool isValid(char * s){
    ST st;
    STInit(&st);
    //左括号入栈
    //右括号则出栈
    while(*s)
    {
        if(*s == '{'
        || *s == '('
        || *s == '[')
        {
            STPush(&st,*s);
        }
        else
        {
            if(STEmpty(&st)) 
            {
               STDestroy(&st);
               return false;
            }
            int top=STTop(&st);
            STPop(&st);
            if(*s == '}' && top != '{'
            || *s == ')' && top != '('
            || *s == ']' && top != '[')
            {
                STDestroy(&st);
                return false;
            }
        }
        s++;
    }
    bool ret=STEmpty(&st);
    STDestroy(&st);
    return ret;
}

用队列实现栈

OJ链接
在这里插入图片描述

思路

push数据的时候push到非空的那个队列
pop数据的时候把非空队列的数据转移到空的队列,直到只剩最后一个,然后pop
在这里插入图片描述

注意点

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
局部结构体变量出了作用域销毁,还去返回它的地址,就是野指针了,所以这样写是不对的
应该malloc一个节点后再返回
在这里插入图片描述
不要为了不想把&obj->q1传递给Init而在MyStack中写成队列的指针,这时候这两个指针没有初始化,到Init函数中就有野指针问题。如果实在想在MyStack中写成队列的指针,可以q1和q2再去malloc

在这里插入图片描述

只free(obj)那么链表中的节点就会出现内存泄漏的问题
在这里插入图片描述

代码

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

typedef int QDataType;

//链表队列
typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType data;
}QNode;

//为了方便尾插头插和个数的记录
typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Queue;

//初始化队列
void QueueInit(Queue* pq);
//入队列,尾插
void QueuePush(Queue* pq, QDataType x);
//出队列,头删
void QueuePop(Queue* pq);
//销毁
void QueueDestroy(Queue* pq);
//获取队列中有效元素个数
int QSize(Queue* pq);
//检测队列是否为空
bool QueueEmpty(Queue* pq);
//取队头元素
QDataType QueueFront(Queue* pq);
//取队尾元素
QDataType QueueBack(Queue* pq);

//初始化队列
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = NULL;
	pq->tail = NULL;

	pq->size = 0;
}
//入队列,尾插
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* tmp = (QNode*)malloc(sizeof(QNode));
	if (tmp == NULL)
	{
		perror("malloc fail\n");
		return;
	}
	tmp->data = x;
	tmp->next = NULL;

	if (pq->tail == NULL)
	{
		pq->head = pq->tail = tmp;
	}
	else
	{
		pq->tail->next = tmp;
		pq->tail = tmp;
	}
	pq->size++;
}
//出队列,头删
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}

	pq->size--;
}
//销毁
void QueueDestroy(Queue* pq)
{
	assert(pq);
	//while (!QueueEmpty(pq))
	//{
	//	QNode* next = pq->head->next;
	//	free(pq->head);
	//	pq->head = next;
	//}

	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;
	pq->size = 0;
}
//获取队列中有效元素个数
int QSize(Queue* pq)
{
	assert(pq);

	return pq->size;
}
//检测队列是否为空
bool QueueEmpty(Queue* pq)
{
	assert(pq);

	return pq->head == NULL && pq->tail==NULL;
}
//取队头元素
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->head->data;
}
//取队尾元素
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->tail->data;
}

typedef struct {
    Queue q1;
    Queue q2;
} MyStack;


MyStack* myStackCreate() {
    MyStack* ST=(MyStack*)malloc(sizeof(MyStack));
    if(ST==NULL)
    {
        perror("malloc fail\n");
        return NULL;
    }
    
    QueueInit(&ST->q1);
    QueueInit(&ST->q2);

    return ST;
}

void myStackPush(MyStack* obj, int x) {
    assert(obj);
    //插入非空的那个队列,两个都空则无所谓
    if(!QueueEmpty(&obj->q1))
    {
        QueuePush(&obj->q1,x);
    }
    else
    {
        QueuePush(&obj->q2,x);
    }

}

int myStackPop(MyStack* obj) {
    assert(obj);
    Queue* EmptyQ=&obj->q1;
    Queue* NonEmptyQ=&obj->q2;
    if(!QueueEmpty(EmptyQ))
    {
        NonEmptyQ=&obj->q1;
        EmptyQ=&obj->q2;
    }
    //将非空队列的元素放到空队列,留下一个,然后Pop
    while(QSize(NonEmptyQ)>1)
    {
        QueuePush(EmptyQ,QueueFront(NonEmptyQ));
        QueuePop(NonEmptyQ);
    }
    int top=NonEmptyQ->head->data;
    QueuePop(NonEmptyQ);
    return top;
}

int myStackTop(MyStack* obj) {
    assert(obj);
    if(!QueueEmpty(&obj->q1))
    {
        return QueueBack(&obj->q1);
    }
    else
    {
        return QueueBack(&obj->q2);
    }
}

bool myStackEmpty(MyStack* obj) {
    assert(obj);
    return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}

void myStackFree(MyStack* obj) {
    assert(obj);

    QueueDestroy(&obj->q1);
    QueueDestroy(&obj->q2);
    free(obj);
}

用栈实现队列

OJ链接
在这里插入图片描述

思路

一个栈负责push
一个栈负责pop

push时放进pushst
pop时如果popst为空,则将pushst中数据都放入popst,然后对popst中数据进行pop
如果popst不为空,则直接对popst中数据进行pop
在这里插入图片描述

代码

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
#include<string.h>

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;

void STInit(ST* pst);

void STDestroy(ST* pst);

void STPush(ST* pst,STDataType x);

void STPop(ST* pst);

STDataType STTop(ST* pst);

bool STEmpty(ST* pst);

int STSize(ST* pst);

void STInit(ST* pst)
{
	assert(pst);
	pst->a = NULL;
	pst->top = 0;//top指向栈顶元素的下一个位置
	pst->capacity = 0;
}

void STDestroy(ST* pst)
{
	assert(pst);
	free(pst->a);
	pst->a = NULL;
	pst->capacity = pst->top = 0;
}

void STPush(ST* pst, STDataType x)
{
	assert(pst);
	if (pst->top == pst->capacity)
	{
		int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(pst->a, newcapacity*sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("realloc fail\n");
			return;
		}
		pst->a = tmp;
		pst->capacity = newcapacity;
	}
	pst->a[pst->top++] = x;
}

void STPop(ST* pst)
{
	assert(pst);
	assert(!STEmpty(pst));
	pst->top--;
}

STDataType STTop(ST* pst)
{
	assert(pst);
	assert(!STEmpty(pst));
	return pst->a[pst->top - 1];
}

bool STEmpty(ST* pst)
{
	assert(pst);
	return pst->top == 0;
}

int STSize(ST* pst)
{
	assert(pst);
	return pst->top;
}

typedef struct {
    ST s1;//第一个栈用来存数据
    ST s2;//第二个栈用来出数据
} MyQueue;


MyQueue* myQueueCreate() {
    MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));
    if(obj==NULL)
    {
        perror("malloc fail\n");
        return NULL;
    }

    STInit(&obj->s1);
    STInit(&obj->s2);

    return obj;
}

void myQueuePush(MyQueue* obj, int x) {
    assert(obj);
    //放到存数据的栈
    STPush(&obj->s1,x);
}

int myQueuePop(MyQueue* obj) {
    int front=myQueuePeek(obj);
    STPop(&obj->s2);

    return front;
}

int myQueuePeek(MyQueue* obj) {
    //如果用来出数据的栈(s2)为空,那么将s1栈中数据移动到s2的栈
    if(STEmpty(&obj->s2))
    {
        while(STSize(&obj->s1)>0)
        {
           STPush(&obj->s2,STTop(&obj->s1));
           STPop(&obj->s1);
        }
    }
    
    return STTop(&obj->s2);
}

bool myQueueEmpty(MyQueue* obj) {
    return STEmpty(&obj->s1) && STEmpty(&obj->s2);
}

void myQueueFree(MyQueue* obj) {
    STDestroy(&obj->s1);
    STDestroy(&obj->s2);
    free(obj);
}

设计循环队列

OJ链接
在这里插入图片描述

思路

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
无法确定满的时候的状态
解决方案:

1.多开一个空间。满:real+1 == front

2.增加一个size变量记录数据个数

空:size==0

满:size==8

这里展示多开一个空间的方案
在这里插入图片描述
循环队列可以用链表实现也可以用数组实现

链表实现思路:
空:front == rear
满:rear->next == front
在这里插入图片描述

在这里插入图片描述
由于需要获取队尾元素,
解决思路有:1.双向链表 2.增加一个prev指针 3.遍历获得队尾数据

数组实现思路:
空:front == real
满:(rear+1)%(k+1) == front
在这里插入图片描述
相比来说数组实现会简单一些,因为链表实现起来结构更复杂

数组实现代码

typedef struct {
    int* a;
    int front;
    int real;
    int k;
} MyCircularQueue;

bool myCircularQueueIsEmpty(MyCircularQueue* obj);
bool myCircularQueueIsFull(MyCircularQueue* obj);

MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue*obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    obj->a=(int*)malloc(sizeof(int)*(k+1));//多开一个空间方便判满
    obj->front=0;
    obj->real=0;
    obj->k=k;

    return obj;
}

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    if(myCircularQueueIsFull(obj))
    return false;
    obj->a[obj->real++]=value;
    obj->real%=(obj->k+1);
    return true;
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    return false;
    obj->front++;
    obj->front%=(obj->k+1);
    return true;
}

int myCircularQueueFront(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    return -1;

    return obj->a[obj->front];
}

int myCircularQueueRear(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    return -1;

    if(obj->real==0)
    return obj->a[obj->k];
    else
    return obj->a[obj->real-1];
}

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    return obj->front==obj->real;
}

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    return (obj->real+1)%(obj->k+1)==obj->front;
}

void myCircularQueueFree(MyCircularQueue* obj) {
    free(obj->a);
    obj->real=obj->front=obj->k=0;
    free(obj);
}

链表实现代码

typedef struct QueueNode
{
    struct QueueNode*next;
    int data;
}QNode;

typedef struct {
    QNode*front;
    QNode*real;
    QNode*prev;
} MyCircularQueue;

bool myCircularQueueIsEmpty(MyCircularQueue* obj);
bool myCircularQueueIsFull(MyCircularQueue* obj);

QNode* QueueInit(int k)
{
    QNode*phead=(QNode*)malloc(sizeof(QNode));
    QNode*cur=phead;
    while(k--)
    {
        QNode*next=(QNode*)malloc(sizeof(QNode));
        cur->next=next;
        cur->data=0;
        next->next=phead;
        cur=next;
    }
    return phead;
}

MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue*obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    if(obj==NULL)
    {
        perror("malloc fail\n");
        return NULL;
    }

    QNode*phead=QueueInit(k);
    obj->front=phead;
    obj->real=phead;
    obj->prev=NULL;
    return obj;
}

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    if(myCircularQueueIsFull(obj))
    return false;

    obj->real->data=value;
    obj->prev=obj->real;//记录前一个
    obj->real=obj->real->next;

    return true;
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    return false;

    obj->front=obj->front->next;
    return true;
}

int myCircularQueueFront(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    return -1;


    return obj->front->data;
}

int myCircularQueueRear(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    return -1;

    return obj->prev->data;
}

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
   return obj->front==obj->real;
}

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    return obj->real->next==obj->front;
}

void myCircularQueueFree(MyCircularQueue* obj) {
    QNode*cur=obj->front;
    QNode*next=cur->next;
    while(next!=obj->front)
    {
        free(cur);
        cur=next;
        next=cur->next;
    }
    free(cur);

    obj->front=NULL;
    obj->real=NULL;
    obj->prev=NULL;
    free(obj);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/539150.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

洛谷P1157详解(两种解法,一看就会)

一、问题引出 组合的输出 题目描述 排列与组合是常用的数学方法&#xff0c;其中组合就是从 n n n 个元素中抽出 r r r 个元素&#xff08;不分顺序且 r ≤ n r \le n r≤n&#xff09;&#xff0c;我们可以简单地将 n n n 个元素理解为自然数 1 , 2 , … , n 1,2,\dot…

chatgpt赋能Python-pycharm桌面图标变白

PyCharm是一个非常流行的Python集成开发环境&#xff0c;它可以帮助Python开发人员更快更高效地编写代码。但是&#xff0c;有些用户可能会遇到一个问题&#xff1a;他们的PyCharm桌面图标突然变成了白色&#xff0c;而不是原来的彩色图标。在这篇文章中&#xff0c;我将详细介…

面试官:为什么有了sleep还需要wait?

1. 能不能调整线程先后顺序&#xff1f; 对于线程执行最大的问题就是随机调度&#xff0c;抢占式执行&#xff0c;对于程序猿来讲&#xff0c;是不喜欢这种随机性的&#xff0c;程序猿喜欢确定的东西&#xff0c;于是就有了一些方法&#xff0c;可以控制线程之间的执行顺序&…

Keil 手动添加自己的lib库

我是在做一个项目看蓝牙模块官方Demo程序时发现对库的使用&#xff0c; 库大家都知道是不需要编译的&#xff0c;而且别人是无法看到源代码的&#xff0c;这样的好处就是编译快&#xff0c;并且方便移植&#xff0c;更安全。 我的制作步骤如下&#xff1a; 1、首先要把整个工程…

大量电脑桌面文件一键批量复制移动

电脑桌面上的文件越来越多&#xff0c;处理起来越来越繁琐。如果需要把这些文件复制或移动到另一个文件夹中&#xff0c;手动一个个复制或移动不仅费时费力&#xff0c;还容易出错。那么有没有什么方法可以快速批量复制和移动这些文件呢&#xff1f;当然有&#xff01;今天小编…

若依前后端分离如何动态渲染echarts图表

本章教程,主要介绍一下如何在若依前后端分离框架中,进行echarts动态渲染数据。 ECharts是一款基于JavaScript的数据可视化图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。ECharts最初由百度团队开源,并于2018年初捐赠给Apache基金会,成为ASF孵化级项目。…

027python-ddt

在unittest中&#xff0c;测试用例是不能传self以外的参数的&#xff0c;否则会报错import unittestclass TeatMath(unittest.TestCase):# def test_add(self,q): # TypeError: TeatMath.test_add() missing 1 required positional argument: q——>测试用例传参报错def t…

【KD-Tree】基于k-d树的KNN算法实现

文章目录 一、什么是KD-Tree&#xff1f;二、k-d树的结构三、k-d树的创建四、k-d树的应用五、KD-Tree的优缺点 例题JZPFAR 一、什么是KD-Tree&#xff1f; KD-Tree&#xff0c;又称&#xff08;k-dimensional tree&#xff09;&#xff0c;是一种基于二叉树的数据结构。它可以…

大项目推进

拉取最新的小组分支&#xff0c;创建自己开发分支&#xff08;对应实现人&#xff09; 任务分支&#xff08;小组名-功能名-执行人&#xff0c;如&#xff1a;f1-login-zhangfei&#xff09; 根据业务流程整理文档梳理与书写 定义领域模型&#xff08;包括&#xff1a;query、…

通用医学人工智能基础模型(GMAI)

最近&#xff0c;Eric J. Topol和 Pranav Rajpurkar研究团队提出了一个通用医学人工智能基础模型&#xff0c;文章名字《Foundation models for generalist medical artificial intelligence》 模型研究进展包括&#xff1a;多模态架构&#xff0c;和自监督学习技术&#xff0…

知识库AI机器人客服接口对接-唯一客服系统文档中心

如果你的需求仅仅是对接自训练的ChatGPT接口&#xff0c;实现自己的个性化机器人&#xff0c;那么可以看看下面的个性化ChatGPT调用接口前提条件是已经搭建好了知识库服务&#xff0c;该服务默认监听端口8083 chat接口地址 POST http://127.0.0.1:8083/data_collection/searchS…

“伙伴+华为”体系,数字时代的新航标

如果从1994年中国实行税制改革&#xff0c;要求以“以计算机网络为依托”开展企业税务工作算起&#xff0c;转瞬间&#xff0c;中国企业的信息化、数字化建设已经走过了近三十年历程。 这期间&#xff0c;信息化、数字化成为了企业走向管理现代化、全球化的依托&#xff0c;成为…

最新版本的Android studio 集成高德地图的定位功能

android studio版本&#xff1a; 1、根据高德官网链接集成 2、配置key的时候有两个注意点&#xff1a; a .获取安全SHA1 根据高德推荐的方式获取时&#xff0c;可能C:\Program Files\Android\Android Studio\jre\bin目录下找不到keytool.exe; 可以根据以下方式获取&#xff1…

华为新模拟器eNSPLite下载,部署教程及产品使用文档

华为新模拟器eNSPLite下载&#xff0c;部署教程及产品使用文档 如需下载请到我的博客中下载 硬件要求 数通培训认证模拟器支持在个人PC和物理服务器上部署安装&#xff0c;如下所示。 硬件推荐配置CPUX86_64架构CPU&#xff0c;支持VT-x/AMD-V 8核或以上RAM16G或以上DISK40G以…

数据库信息速递 支持机器学习的10个数据库 (译)

开头还是介绍一下群&#xff0c;如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;在新加的朋友会分到2群&#xff08;共…

Spring:自动装配 Bean 的两种方式、使用注解开发

文章目录 Spring&#xff1a;Day 02一、自动装配 Bean1. 搭建环境2. 自动装配方式一&#xff1a;xml 配置3. 自动装配方式二&#xff1a;注解 二、注解开发三、使用 JavaConfig 实现配置 Spring Spring&#xff1a;Day 02 一、自动装配 Bean 在 Spring 中有三种装配的方式&am…

PostgreSQL表用户列最大个数

PostgreSQL表用户列最大个数 有些业务可能有这么个需求&#xff1a;需要增加用户列&#xff0c;即通过ALTER TABLE ... ADD...来添加用户列。那么PG/GP中是否会有列个数的限制呢&#xff1f; 它有1600列数的限制&#xff0c;并且没有方法去除掉这个限制。参见&#xff1a; http…

千年平阴玫瑰,绽放数字新魅力

“人间美景五月天、玫瑰花放霞流丹。” 每年的五月&#xff0c;济南市平阴县总是一幅玫瑰花芳香如海的迷人景象。作为中国玫瑰之乡&#xff0c;平阴地处古东原之阴&#xff0c;位于北纬36度“玫瑰种植黄金带”之上&#xff0c;这里土肥地沃、气候温和&#xff0c;属暖温带大陆…

Netty实战(四)

本节我们看看Netty的传输&#xff08;全是干货&#xff0c;自带水杯&#xff09; 一、Java的NIO和OIO1.1 OIO1.2 NIO 二、Netty的NIO和OIO2.1 OIO2.2 NIO 三、传输API四、内置的传输4.1 NIO4.2 Epoll—用于 Linux 的本地非阻塞传输4.3 OIO4.4 用于 JVM 内部通信的 Local 传输4.…

chatgpt赋能Python-pycharm如何关联python

PyCharm如何关联Python 作为一款被广泛使用的Python集成开发环境&#xff08;IDE&#xff09;&#xff0c;PyCharm为Python程序员提供了丰富的开发工具和功能。在开始使用PyCharm之前&#xff0c;我们需要确保PyCharm已经正确地关联了Python。在本篇文章中&#xff0c;我们将介…