【数据结构初阶】单链表(附全部码源)

news2024/11/24 14:29:10

单链表

    • 1,单链表的概念及结构
    • 2,单链表的实现
      • 2.1初始化内容(所需文件,接口)
      • 2.2申请结点
      • 2.3打印单链表
      • 2.4尾插
      • 2.5头插
      • 2.6尾删
      • 2.7头删
      • 2.8查找
      • 2.9在pos位置之后插入
      • 2.10在pos位置前面插入
      • 2.11删除pos之后的值
      • 2.12删除pos位置的值
      • 2.13销毁链表
    • 3.全部码源

1,单链表的概念及结构

概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。
在这里插入图片描述
在这里插入图片描述
现实中 数据结构中
在这里插入图片描述

2,单链表的实现

2.1初始化内容(所需文件,接口)

所需文件

头文件->SList.h
源文件->test.c
源文件->SList.c

接口(SList.h中)

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

typedef int SLTDateType;
typedef struct SListNode
{
	SLTDateType date;
	struct SListNode* next;
}SLTNode;

//打印单链表
void SLTPrint(SLTNode* phead);

//创造结点
SLTNode* BuySListNode(SLTDateType x);

//尾插
void SLTPushBack(SLTNode** pphead, SLTDateType x);

//头插
void SLTPushFront(SLTNode** pphead, SLTDateType x);

//尾删
void SLTPopBack(SLTNode** pphead);

//头删
void SLTPopFront(SLTNode** pphead);

//查找内容
SLTNode* SLTFind(SLTNode* phead, SLTDateType x);

//在pos之前插入
void SLTInsert(SLTNode** pphead, SLTDateType x);

//在pos之后插入
void SLTInsertAfter(SLTNode** pphead, SLTDateType x);

//删除pos位置
void SLTErase(SLTNode** pphead, SLTDateType x);

//删除pos的后一个位置
void SLTEraseAfter(SLTNode** pphead, SLTDateType x);

2.2申请结点

SLTNode* BuySListNode(SLTDateType x)
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode*));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	else
	{
		newnode->date = x;
		newnode->next = NULL;
	}
	return newnode;
}

2.3打印单链表

void SLTPrint(SLTNode* phead)
{
	SLTNode* cur = phead;
	while (cur)
	{
		printf("%d->", cur->date);
		cur = cur->next;
	}
	printf("NULL\n");
}

2.4尾插

void SLTPushBack(SLTNode** pphead, SLTDateType x)
{
    assert(pphead);//pphead不能为空,pphead为空说明里面没有存指向头节点指针的地址,那就说明没有链表
	SLTNode* newnode = BuySListNode(x);//由于在头插和随机插入的过程中也会涉及到节点的创建,所以这里把节点的创建单独封装了一个函数

	if (*pphead == NULL)
	{
		*pphead = newnode;
	}
	else
	{
		SLTNode* tail = *pphead;
		while (tail->next != NULL)//假如链表为空这里就非法访问了,因此要先判断
		{
			tail = tail->next;
		}
		tail->next = newnode;
	}
}

2.5头插

头插显然是要改变头指针存放的地址,因此形参也需要传递二级指针。头插无需单独考虑空链表的情况

void SLTPushFront(SLTNode** pphead, SLTDateType x)
{
	SLTNode* newnode = BuySListNode(x);
	newnode->next = *pphead;
	*pphead = newnode;
}

2.6尾删

尾删先要遍历一遍链表找到最后一个节点将其释放掉,还要找到倒数第二个节点将它的指针域中存的地址改为NULL。所以定义两个指针让他们同时去遍历链表,一个找尾,另一个找倒数第二个节点。需要注意的是空链表和只有一个节点的链表的情况,空链表无法进行尾删,而只有一个节点的链表在尾删后会变成一个空链表,这意味着要改变头指针里面存放的地址,所以尾删形参也要传递二级指针。

void SLTPopBack(SLTNode** pphead)
{
    assert(pphead);
	assert(*pphead);//暴力检查是否为空链表,空链表不能删数据
	/*if (*pphead == NULL)//温柔的进行检查
	{
		return;
	}*/
	//只有一个节点
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	//有多个节点
	else
	{
		/*SLTNode* tailPrev = NULL;
		SLTNode* tail = *pphead;
		while (tail->next != NULL)
		{
			tailPrev = tail;
			tail = tail->next;
		}
		free(tail);
		tailPrev = NULL;*/
		SLTNode* tail = *pphead;
		while (tail->next->next)
		{
			tail = tail->next;
		}
		free(tail->next);
		tail->next = NULL;
	}
}

2.7头删

头删很明显需要改变头指针中存放的地址,所以形参仍然需要传递二级指针。头删只需要注意链表是否为空,空链表无法进行删除。此外在进行头删的时候记得将原来的头节点释放掉,因此在改变头节点之前需要先保留原来头结点的地址,否则在更换完新的头节点后就找不到原来的头节点了。

void SLTPopFront(SLTNode** pphead)
{
	assert(pphead);

	assert(*pphead);

	SLTNode* newnode = (*pphead)->next;//假如链表为空,这里就会发生越界,因此要判断链表是否为空
	free(*pphead);
	*pphead = newnode;
}

2.8查找

其实就是遍历一遍链表,但是只能返回第一次出现的地址。查找可以当修改来使用,我们查找到节点的地址后就可以通过地址去修改数据域中存储的数据。

SLTNode* SLTFind(SLTNode* phead, SLTDateType x)
{
	SLTNode* cur = phead;
	while (cur)
	{
		if (cur->date == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

2.9在pos位置之后插入

先让newnode的指针域存储pos后一个节点的地址,再让pos的指针域存newnode的地址

void SLTInsertAfter(SLTNode* pos, SLTDateType x)
{
	assert(pos);
	SLTNode* newnode = BuySListNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

2.10在pos位置前面插入

和尾插类似,但此时只需要遍历链表找到pos位置的前一个节点即可,同样需要注意pos是头结点的情况,此时就成头插了,需要改变头指针中存的地址,因此函数的形参需要传二级指针。

void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDateType x)
{
	assert(pphead);
	assert(pos);
	if (pos == *pphead)
	{
		SLTPushFront(pphead, x);
	}
	else
	{
		SLTNode* prev = *pphead;
		if (prev->next != pos)
		{
			prev = prev->next;
		}
		SLTNode* newnode = BuySListNode(x);
		prev->next = newnode;
		newnode->next = pos;
	}
}

2.11删除pos之后的值

注意不能写成后面这样:pos->next = pos->next->next。这样写虽然把pos位置后面的节点从链表中剔除出去了,但并没有真正意义上的实现删除,因为每一个节点都是通过malloc在堆上申请的,不使用的时候要主动的去释放掉,也就是free掉,把这块空间归还给操作系统,否则会导致内存泄漏。而上面那样写,就会导致pos后面的节点丢失,无法进行释放,正确的做法是在执行这条语句之前把pos后边节点的地址先保存起来。

void SLTEraseAfter(SLTNode* pos)
{
	assert(pos);
	//检查pos是不是尾结点
	assert(pos->next);

	SLTNode* posNext = pos->next;

	pos->next = posNext->next;
	free(posNext);
	posNext = NULL;
}

2.12删除pos位置的值

pos可能是头结点的地址,因此形参要用二级指针。

void SLTErase(SLTNode** pphead, SLTNode* pos)
{
	assert(pphead);
	assert(pos);

	if (pos == *pphead)
	{
		SLTPopFront(pphead);
	}
	else
	{
		SLTNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = pos->next;
		free(pos);
	}
}

2.13销毁链表

void SListDestroy(SLTNode* plist)
{
	assert(plist);
	SLTNode* cur = plist;
	while (cur)
	{
		SLTNode* pur = cur;
		cur = cur->next;
		free(pur);
	}
}

3.全部码源

SList.c

#include"SList.h"

void SLTPrint(SLTNode* phead)
{
	SLTNode* cur = phead;
	//while (cur != NULL)
	while (cur)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}

	printf("NULL\n");
}

SLTNode* BuySListNode(SLTDataType x)
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}

	newnode->data = x;
	newnode->next = NULL;

	return newnode;
}

// 16:07继续
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
	SLTNode* newnode = BuySListNode(x);

	if (*pphead == NULL)
	{
		// 改变的结构体的指针,所以要用二级指针
		*pphead = newnode;
	}
	else
	{
		SLTNode* tail = *pphead;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}

		// 改变的结构体,用结构体的指针即可
		tail->next = newnode;
	}	
}

void SLTPushFront(SLTNode** pphead, SLTDataType x)
{
	SLTNode* newnode = BuySListNode(x);

	newnode->next = *pphead;
	*pphead = newnode;
}

void SLTPopBack(SLTNode** pphead)
{
	// 1、空
	assert(*pphead);

	// 2、一个节点
	// 3、一个以上节点
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	else
	{
		//SLTNode* tailPrev = NULL;
		//SLTNode* tail = *pphead;
		//while (tail->next)
		//{
		//	tailPrev = tail;
		//	tail = tail->next;
		//}

		//free(tail);
		tail = NULL;
		//tailPrev->next = NULL;

		SLTNode* tail = *pphead;
		while (tail->next->next)
		{
			tail = tail->next;
		}

		free(tail->next);
		tail->next = NULL;
	}
}

void SLTPopFront(SLTNode** pphead)
{
	assert(pphead);

	// 空
	assert(*pphead);

	// 非空
	SLTNode* newhead = (*pphead)->next;
	free(*pphead);
	*pphead = newhead;
}

SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
{
	SLTNode* cur = phead;
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}

		cur = cur->next;
	}

	return NULL;
}

void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
	assert(pphead);
	assert(pos);

	if (pos == *pphead)
	{
		SLTPushFront(pphead, x);
	}
	else
	{
		SLTNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}

		SLTNode* newnode = BuySListNode(x);
		prev->next = newnode;
		newnode->next = pos;
	}
}

// 在pos以后插入x
void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{
	assert(pos);

	SLTNode* newnode = BuySListNode(x);
	pos->next = newnode;
	newnode->next = pos->next;
}

// 删除pos位置
void SLTErase(SLTNode** pphead, SLTNode* pos)
{
	assert(pphead);
	assert(pos);

	if (pos == *pphead)
	{
		SLTPopFront(pphead);
	}
	else
	{
		SLTNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}

		prev->next = pos->next;
		free(pos);
		//pos = NULL;
	}
}

// 删除pos的后一个位置
void SLTEraseAfter(SLTNode* pos)
{
	assert(pos);

	// 检查pos是否是尾节点
	assert(pos->next);

	SLTNode* posNext = pos->next;

	pos->next = posNext->next;

	free(posNext);
	posNext = NULL;
}

SList.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>


typedef int SLTDataType;

typedef struct SListNode
{
	SLTDataType data;
	struct SListNode* next;
}SLTNode;

void SLTPrint(SLTNode* phead);

SLTNode* BuySListNode(SLTDataType x);
void SLTPushBack(SLTNode** pphead, SLTDataType x);
void SLTPushFront(SLTNode** pphead, SLTDataType x);

void SLTPopBack(SLTNode** pphead);
void SLTPopFront(SLTNode** pphead);


SLTNode* SLTFind(SLTNode* phead, SLTDataType x);

// 在pos之前插入x
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);

// 在pos以后插入x
void SLTInsertAfter(SLTNode* pos, SLTDataType x);

// 删除pos位置
void SLTErase(SLTNode** pphead, SLTNode* pos);

// 删除pos的后一个位置
void SLTInsertAfter(SLTNode* pos);

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"SList.h"

void TestSList1()
{
	int n;
	printf("请输入链表的长度:");
	scanf("%d", &n);
	printf("\n请依次输入每个节点的值:");
	SLTNode* plist = NULL;

	for (size_t i = 0; i < n; i++)
	{
		int val;
		scanf("%d", &val);
		SLTNode* newnode = BuySListNode(val);

		// 头插
		newnode->next = plist;
		plist = newnode;
	}

	SLTPrint(plist);

	SLTPushBack(&plist, 10000);
	SLTPrint(plist);
}

void TestSList2()
{
	SLTNode* plist = NULL;
	SLTPushBack(&plist, 1);
	SLTPushBack(&plist, 2);
	SLTPushBack(&plist, 3);
	SLTPushBack(&plist, 4);
	SLTPushBack(&plist, 5);
	SLTPrint(plist);

	SLTPushFront(&plist, 10);
	SLTPushFront(&plist, 20);
	SLTPushFront(&plist, 30);
	SLTPushFront(&plist, 40);
	SLTPrint(plist);
}

void TestSList3()
{
	SLTNode* plist = NULL;
	SLTPushBack(&plist, 1);
	SLTPushBack(&plist, 2);
	SLTPushBack(&plist, 3);
	SLTPushBack(&plist, 4);
	SLTPushBack(&plist, 5);
	SLTPrint(plist);


	SLTPopBack(&plist);
	SLTPrint(plist);

	SLTPopBack(&plist);
	SLTPrint(plist);

	SLTPopBack(&plist);
	SLTPrint(plist);

	SLTPopBack(&plist);
	SLTPrint(plist);

	SLTPopBack(&plist);
	SLTPrint(plist);

	// SLTPopBack(&plist);
	// SLTPrint(plist);
}

void TestSList4()
{
	SLTNode* plist = NULL;
	SLTPushBack(&plist, 1);
	SLTPushBack(&plist, 2);
	SLTPushBack(&plist, 3);
	SLTPushBack(&plist, 4);
	SLTPushBack(&plist, 5);
	SLTPrint(plist);

	SLTPopFront(&plist);
	SLTPrint(plist);

	SLTPopFront(&plist);
	SLTPrint(plist);

	SLTPopFront(&plist);
	SLTPrint(plist);

	SLTPopFront(&plist);
	SLTPrint(plist);

	SLTPopFront(&plist);
	//SLTPopFront(&plist);
	SLTPrint(plist);
}

void TestSList5()
{
	SLTNode* plist = NULL;
	SLTPushBack(&plist, 1);
	SLTPushBack(&plist, 2);
	SLTPushBack(&plist, 3);
	SLTPushBack(&plist, 4);
	SLTPushBack(&plist, 5);
	SLTPrint(plist);

	SLTNode* pos = SLTFind(plist, 3);
	SLTInsert(&plist, pos, 30);
}


void TestSList6()
{
	SLTNode* plist = NULL;
	SLTPushBack(&plist, 1);
	SLTPushBack(&plist, 2);
	SLTPushBack(&plist, 3);
	SLTPushBack(&plist, 4);
	SLTPushBack(&plist, 5);
	SLTPrint(plist);

	int x;
	scanf("%d", &x);
	SLTNode* pos = SLTFind(plist, x);
	if (pos)
	{
		SLTInsertAfter(pos, x * 10);
	}
	SLTPrint(plist);
}

void TestSList7()
{
	SLTNode* plist = NULL;
	SLTPushBack(&plist, 1);
	SLTPushBack(&plist, 2);
	SLTPushBack(&plist, 3);
	SLTPushBack(&plist, 4);
	SLTPushBack(&plist, 5);
	SLTPrint(plist);

	int x;
	scanf("%d", &x);
	SLTNode* pos = SLTFind(plist, x);
	if (pos)
	{
		//SLTErase(&plist, pos);
		SLTEraseAfter(pos);
		pos = NULL;
	}
	SLTPrint(plist);

	SLTPopFront(&plist);
	SLTPrint(plist);

	SLTPopFront(&plist);
	SLTPrint(plist);

	SLTPopFront(&plist);
	SLTPrint(plist);

	SLTPopFront(&plist);
	SLTPrint(plist);

}
int main()
{
	TestSList4();

	return

💘不知不觉,【数据结构初阶】单链表以告一段落。通读全文的你肯定收获满满,让我们继续为数据结构学习共同奋进!!!

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

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

相关文章

2023亚太杯数学建模思路 - 案例:ID3-决策树分类算法

文章目录 0 赛题思路1 算法介绍2 FP树表示法3 构建FP树4 实现代码 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 算法介绍 FP-Tree算法全称是FrequentPattern Tree算法&#xff0c;就是频繁模…

接口测试系列之 —— 接口安全测试

“开源 Web 应用安全项目”(OWASP)在 2019 年发布了 API 十大安全风险 《OWASP API 安全 Top10》&#xff1a;失效的对象级别授权、失效的用户身份验证、过 度的数据暴露、资源缺乏和速率限制、失效的功能级授权、批量分配、安全配置 错误、注入、资产管理不当、日志和监视不足…

百家网约车平台发布“阳光五条” 多举措加强司机保障

11月17日&#xff0c;免佣联盟百家网约车平台发布“阳光五条”&#xff0c;通过加大免佣力度、实行车费保镖司机版、72小时保护期等措施&#xff0c;加强对网约车司机的权益保障。 近年&#xff0c;交通运输部推动交通运输新业态平台企业落实“阳光行动”等工作&#xff0c;加…

图像分类系列(三) GoogLeNet InceptionV1学习详细记录

前言 ​ 在上一期中介绍了VGG&#xff0c;VGG在2014年ImageNet 中获得了定位任务第1名和分类任务第2名的好成绩&#xff0c;而今天要介绍的就是同年分类任务的第一名——GoogLeNet 。 ​ 作为2014年ImageNet比赛冠军&#xff0c;GoogLeNet 比VGG更深的网络&#xff0c;比Alex…

11月17日,国家大基金三期隆重开启,共同见证芯片产业新时代!

11月17日&#xff0c;国家大基金三期隆重开启&#xff0c;共同见证芯片产业新时代&#xff01; 自国家大基金二期于2019年10月注册成立以来&#xff0c;一直积极响应国家战略和新兴行业发展规划&#xff0c;对设计创新行业的投资加大规模&#xff0c;比如智能汽车、智能电网、人…

初识Linux:目录的创建销毁

目录 ​编辑 提示&#xff1a;以下指令均在Xshell 7 中进行 零、桌面的本质 &#x1f4bb; 扩展&#x1f387;&#xff1a; 一、cd指令&#xff1a; 1、cd - &#xff1a; 2、cd ~&#xff1a; 重命名命令&#xff1a;alias 二、stat指令 冷知识&#xff1a; 如果…

如何在工作外发展副业?主业和副业该如何权衡

有一句话说得好&#xff0c;不要把所有的鸡蛋放在一个篮子里。在面对繁忙的工作生活之外&#xff0c;想要拥有额外的收入来源那就是做一份不影响主业的副业。而副业的发展&#xff0c;不仅能够增加收入&#xff0c;更可以拓展个人的技能和兴趣。 主业跟副业该如何权衡呢&#x…

时间序列预测(6) — ARIMA实现单输入单输出负荷预测

目录 1 数据准备与可视化 2 简单数据探索与清洗 3 差分处理 4 绘制ACF与PACF图像&#xff0c;完成模型选择 5 建立ARIMA和SARIMA模型 5.1 初步建模 5.2 精细化建模 5.3 最终的模型 ARIMA作为成熟的统计学模型已被各种软件以各种方式实现&#xff0c;在Python中我们最常使…

服装鞋帽箱包展示预约小程序的效果是什么

市场上售卖服装、鞋帽箱包的品牌店或小店摊贩非常多&#xff0c;同时这些产品又是人们生活的必需品&#xff0c;以前购买服装等纺织产品&#xff0c;消费者习惯前往线下商场或品牌店&#xff0c;但如今更多的消费者习惯于线上购买&#xff0c;传统门店经营面临困境。 通过【雨科…

暖阳脚本_ 定制企业软件开发的4个趋势:AI、RPA、云应用、边缘计算

根据 Statista 的统计数据显示&#xff0c;企业级软件市场在全球范围内占据了领先地位&#xff0c;预测到2028年&#xff0c;市场规模将接近3760亿美元。企业应用软件市场的稳健增长&#xff0c;甚至在经济不景气的时候也能持续&#xff0c;这充分表明软件解决方案对于提升企业…

使用 Redis BitMap 实现签到与查询历史签到以及签到统计功能(SpringBoot环境)

目录 一、前言二、Redis BitMap 位图原理2.1、BitMap 能解决什么2.2、BitMap 存储空间计算2.3、BitMap 存在问题 三、Redis BitMap 操作基本语法和原生实现签到3.1、基本语法3.2、Redis BitMap 实现签到操作指令 四、SpringBoot 使用 Redis BitMap 实现签到与统计功能4.1、代码…

避雷指南:电视盒子哪个牌子最好?最具性价比电视盒子排行榜

电视盒子有些会出现死机和卡顿&#xff0c;广告植入过多&#xff0c;操作复杂等问题&#xff0c;大家在选购时极易踩雷&#xff0c;我身为数码测评员&#xff0c;本期测评的主题是电视盒子哪个牌子最好&#xff0c;购入了市面上最热销的电视盒子对比后整理了最具性价比电视盒子…

ubuntu提高 github下载速度

Github一般用于Git的远程仓库&#xff0c;由于服务器位于国外&#xff0c;国内访问速度比较慢&#xff0c;为了提高访问速度&#xff0c;决定绕过DNS域名解析。 获取Github的IP地址 按下ctrl&#xff0b;alt&#xff0b;T打开命令终端&#xff0c;输入&#xff1a; nslookup gi…

数据治理入门

处理模式 模式名称常见场景常见框架批处理夜间几个小时&#xff0c;无人值守hive spark datax流处理7*24H一直运行&#xff0c;无人值守maxwell, flink, flume, kafka即席处理人机交互接口访问 web页面 数据治理的意义 数据质量低&#xff1a;数据错误&#xff0c;不准确或不…

Gooxi国鑫金秋发布会圆满召开,引领数智新未来

10月24日&#xff0c;主题为“芯加速创鑫局”的2023 Gooxi第四代英特尔至强可扩展处理器平台新品发布会隆重召开&#xff0c;Gooxi重磅发布基于第四代英特尔至强可扩展处理器平台系列新品&#xff0c;Gooxi英特尔平台算力迎来全新升级进化&#xff0c;为AI注入全新发展动力&…

微信小程序相机相册授权后,需要重启客户端才能正常调用相机,无法调起窗口选择图片,无反应解决方案

最近微信小程序很多功能突然不能使用&#xff0c;本篇针对无法调起相册进行说明 解决方案 检查小程序隐私协议是否配置&#xff0c;操作步骤这里不在详细说明&#xff0c;点击教程按照上面的教程&#xff0c;找到入口后点击完善或者更新 选择选中的照片或视频这个权限要申请 之…

牛客机考题编程题输入输出

有时空可以练练这里的题目&#xff1a; https://ac.nowcoder.com/acm/contest/5652 做个总结&#xff0c;其实就两种输入类型&#xff1a; 一种是下面这种&#xff0c;需要对输入的每行进行运算 这种就是循环读取每行的数做一个运算&#xff1a; import sys while True:line …

CodeWhisperer--手把手教你使用一个十分强大的工具

Amazon CodeWhisperer 是一款能够帮助我们智能生成代码的工具。经过数十亿行代码的训练&#xff0c;可以根据提示和现有代码实时生成从片段到完整功能的代码建议。类似 Cursor 和 Github Copilot 编码工具。目前&#xff0c;CodeWhisperer 兼容 Python、Java 和 JavaScript&…

扫码看的视频怎么下载?二维码中的视频怎么保存?

二维码中的视频能设置下载吗&#xff1f;现在很多商家或者企业都会通过制作活码二维码的方式来将展示产品或者企业&#xff0c;当用二维码生成器做二维码时&#xff0c;有什么方法能够让扫码用户可以下载视频观看呢&#xff1f;现在很多的视频二维码只能观看&#xff0c;无法让…