【数据结构】顺序表的概念及实现

news2024/11/24 14:57:52

顺序表

  • 1、顺序表概念
  • 2、初始化顺序表
  • 3、销毁顺序表
  • 4、判断顺序表是否为空
  • 5、打印顺序表
  • 6、检查顺序表的容量(同时充当扩容任务)
  • 7、顺序表的尾插
  • 8、顺序表的头插
  • 9、顺序表的尾删
  • 10、顺序表的头删
  • 11、查找顺序表中某个数的位置
  • 12、在顺序表pos位置插入数字x
  • 13、删除顺序表中pos位置的值

1、顺序表概念

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采取数组存储。在数组上完成数据的增删查改。

顺序表一般可分为:
1.静态顺序表:使用定长数组存储元素。如下:

//静态的顺序表,存储的数据是固定的,N个
#define N 10
typedef int SLDataType;
typedef struct SeqList
{
	SLDataType a[N]; //定长数组
	int size; //存储数据的个数
}SL;

1.如代码所示,这个顺序表最多只能存储十个元素,也就是说当想要存储的元素超过十个时,这个结构没有办法进行存储。

2.动态顺序表

typedef int SLDataType;
typedef struct SeqList
{
	SLDataType* a;
	int size; //存储数据的个数
	int capacity;  //顺序表的容量
}SL;

1.结构体中用了一个整形的指针指向一个动态开辟的存储空间(数组),因此这块空间可以扩大,一旦存储空间不够了,可以随时扩容。
2.这个表示顺序表的结构体中还定义了用来表明顺序表当前存储元素的个数size,和顺序表总的容量capacity。

2、初始化顺序表

//初始化函数
void SLInit(SL* psl)
{
	assert(psl);
	psl->a = NULL;
	psl->capacity = psl->size = 0;
}

1.当顺序表为空的时候,也就意味着还没有动态开辟空间,将指向动态开辟空间的指针置空。
2.顺序表中的元素个数和总的容量此时也为零。

3、销毁顺序表

//销毁函数
void SLDestory(SL* psl)
{
	assert(psl);
	if (psl->a)   //销毁顺序表,要保证顺序表不为空
	{
		free(psl->a);
		psl->a = NULL;
		psl->capacity = psl->size = 0;
	}
}

1.要销毁顺序表说明顺序表中有数据,即销毁顺序表时,要保证顺序表不为空。
2.直接将指向动态开辟的这块存储空间free掉,置为空,当前存储元素个数和总的容量设为0,顺序表也就被销毁了。

4、判断顺序表是否为空

//判空函数
bool SLEmpty(SL* psl)
{
	assert(psl);
	return psl->size == 0;
}

1.如果顺序表存储的元素个数为0的话,为真,返回的是非零,如果不等于的话,为假,返回的是0。

5、打印顺序表

//打印函数
void SLPrintf(SL* psl)
{
	assert(psl);
	assert(!SLEmpty(psl));
	int i = 0;
	for (i = 0; i < psl->size; i++)
	{
		printf("%d ", psl->a[i]);
	}
	printf("\n");
}

1.顺序表是由数组构成的,依次照着数组重头打到尾,顺序表中的元素也就打印出来了。
2.打印顺序表首先要判断顺序表是否为空,因此调用第四节的判空函数。

6、检查顺序表的容量(同时充当扩容任务)

当用顺序表存储数据时,即往顺序表中插入数据,要先判断顺序表当前总的容量是否已经被塞满了,如果被塞满了就需要扩容。

//检查容量
void SLCheckCapacity(SL* psl)
{
	assert(psl);
	if (psl->size == psl->capacity)
	{
		int newCapacity = psl->capacity == 0 ? 4 : psl->capacity * 2;
		SLDataType* tmp = (SLDataType*)realloc(psl->a, newCapacity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			perror("ralloc fail");
			exit(-1);
		}

		psl->a = tmp;
		psl->capacity = newCapacity;
	}
}
  1. 如何判断顺序表已经满了?
    答:当前存储数据的个数与顺序表的总容量相等时,说明顺序表已经满了。
  2. 顺序表满了有两种情况,第一种情况是顺序表中存储的元素真的满了,第二种情况是顺序表为空的情况。
  3. 当顺序表为空时,给顺序表动态开辟四个整型空间的容量,当顺序表不为空又真的满了时,给顺序表动态开辟原先容量两倍的空间。

7、顺序表的尾插

//尾插
void SLPushBack(SL* psl, SLDataType x)
{
	assert(psl);
	SLCheckCapacity(psl);
	psl->a[psl->size] = x;
	psl->size++;
	
}

1.尾插之前检查顺序表的容量,容量不够了直接扩容。
2.因为顺序表是数组构成的,所以顺序表尾插,直接将要插入的数放在数组最后即可,插入完后,表示顺序表存储个数的size加一。

8、顺序表的头插

//头插
void SLPushFront(SL* psl, SLDataType x)
{
	assert(psl);
	SLCheckCapacity(psl);

	//挪动数据,从后往前挪
	int end = psl->size - 1;
	while (end >= 0)
	{
		psl->a[end + 1] = psl->a[end];
		--end;
	}

	psl->a[0] = x;
	psl->size++;
}

1.顺序表要插入数据首先检查顺序表的容量。
2.顺序表是数组,所以头插时,并不能在数组前面再开辟一个空间用来放入新的数据。要实现顺序表的头插只能将数组中的数据一个一个往后移动,第一个位置空出来,才能将数据放入首位置。
在这里插入图片描述
头插数据,挪动数据时要从后面的数据开始挪起,如果从前面的数据开始挪起,后面的数据就会被覆盖。

在主函数中调用头插函数

void TestSeqList1()
{
	SL s;
	SLInit(&s);

	SLPushFront(&s, 8);
	SLPushFront(&s, 6);
	SLPushFront(&s, 5);
	SLPushFront(&s, 4);
	SLPrintf(&s);

	SLPushFront(&s, 12);
	SLPrintf(&s);
}

int main()
{
	TestSeqList1();
	return 0;
}

打印结果
在这里插入图片描述

9、顺序表的尾删

//尾删
void SLPopBack(SL* psl)
{
	assert(psl);
	assert(!SLEmpty(psl));  //顺序表为空时,不能再删除了
	psl->size--;
}

1.只要将数组下标减一,顺序表的尾访问不到,那么就相当于将顺序表的尾删掉了。
2.尾删顺序表的时候要判断顺序表是否为空,如果为空,这不能再删了。

在主函数中调用顺序表的尾删

void TestSeqList2()
{
	SL s;
	SLInit(&s);

	SLPushBack(&s, 3);
	SLPushBack(&s, 6);
	SLPushBack(&s, 9);

	SLPrintf(&s);

	SLPushFront(&s, 8);
	SLPrintf(&s);


	SLPopBack(&s);
	SLPopBack(&s);
	SLPopBack(&s);
	SLPrintf(&s);
	SLPopBack(&s);
	SLPrintf(&s);

	SLPopBack(&s);
}

int main()
{
	TestSeqList2();
	return 0;
}

打印结果
在这里插入图片描述
1.之前插入的数据被一一的尾删到只剩8,将8删除后再进行打印,打印程序段出现报错,因为此时此时已无数据打印。

10、顺序表的头删

//头删
void SLPopFront(SL* psl)
{
	assert(psl);
	assert(!SLEmpty(psl));  //顺序表为空时,不能再删除了

	//挪动数据,从前往后挪
	int cur = 0;
	while (cur < psl->size-1)
	{
		psl->a[cur] = psl->a[cur + 1];
		cur++;
	}
	psl->size--;
}

1.数组中后面的数据依次往前挪,将数组中第一个数据覆盖,顺序表就相当于头删了。
在这里插入图片描述
顺序表头删时,往前挪需要先挪前面的,如果从最后开始挪的话,前面的数据会被覆盖掉。

11、查找顺序表中某个数的位置

查找顺序表中某个数的位置,找了返回这个数据的下标,找不到返回-1。

//查找某个数在顺序表中的位置,并且返回它的下标,没有找到就返回-1
int SLFind(SL* psl, SLDataType x)
{
	assert(psl);

	for (int i = 0; i < psl->size; i++)
	{
		if (psl->a[i] == x)
		{
			return i;

		}
	}

	return - 1;
}

1.遍历整个顺序表,将要找的数与顺序表中数一一比对,相等则说明找到了,返回这个数在数组中的下标。
2.遍历完了还没找到相等的数,说明要找的数在顺序表不存在,返回-1。

在主函数中调用

TestSeqList3()
{
	SL s;
	SLInit(&s);

	SLPushBack(&s, 3);
	SLPushBack(&s, 6);
	SLPushBack(&s, 9);
	SLPushBack(&s, 12);
	SLPushBack(&s, 15);
	SLPushBack(&s, 18);
	SLPrintf(&s);

	int a = SLFind(&s, 6);
	printf("%d\n", a);

}

int main()
{
	TestSeqList3();
	return 0;
}

打印结果
在这里插入图片描述
在顺序表中查找数字6,在数组的第二位被找到,返回他在数组中的下标1。(并且将下标打印了出来)

12、在顺序表pos位置插入数字x

//顺序表在pos位置插入x
void SeqListInsert(SL* psl, size_t pos, SLDataType x)
{
	assert(psl);
	assert(pos <= psl->size);  //等于时即是尾插

	SLCheckCapacity(psl);  //检查容量

	挪动数据
	//size_t end = psl->size - 1;
	//while (end >= pos)
	//{
	//	psl->a[end + 1] = psl->a[end];
	//	--end;
	//}

	//挪动数据
	size_t end = psl->size;
	while (end > pos)
	{
		psl->a[end] = psl->a[end - 1];
		--end;
	}

	psl->a[pos] = x;
	++psl->size;
}

1.顺序表是由数组构成的,数组在物理地址上是连续的,插入时,只能在与数组中相连的地方插入(即头插、尾插、数组中间插入),因此要保证插入的pos位置是小于等于数组最后一个下标的。
2.从最后一个数开始,依次往后挪动,直到挪到pos位置,此时在pos位置插入本来要插入的数。插入完后,将顺序表中表示当前存储数据个数的size加一。
3.上述代码被“注释”掉的是一种又缺陷的写法。当pos为0时候,即头插,此时end==0,进入循环,移动完毕后,end–,end变为-1,因为end为size_t类型(无符号类型),无符号数-1>0,所以还会再次进入循环,形成死循环。
4.头插与尾插都可以在接口中直接调用这段代码。

在主函数中调用

TestSeqList4()
{
	SL s;
	SLInit(&s);

	SLPushBack(&s, 3);
	SLPushBack(&s, 6);
	SLPushBack(&s, 9);
	SLPushBack(&s, 12);
	SLPrintf(&s);

	int x = 0;
	scanf("%d", &x);
	int pos = SLFind(&s, x);
	if (pos != -1)
	{
		SeqListInsert(&s, pos, x*100);
	}
	SLPrintf(&s);

}

int main()
{
	TestSeqList4();
	return 0;
}

打印结果
在这里插入图片描述
1.在pos位置插入首先要找到pos位置,比如在数字9的位置插入,首先要找到数字9的位置
2.在9的位置插入,输入9,此时在这里插入了一个9×100的数,900。

13、删除顺序表中pos位置的值

//顺序表删除pos位置的值
void SeqListErase(SL* psl, size_t pos)
{
	assert(psl);
	assert(pos < psl->size);

	size_t begin = pos;
	while (begin < psl->size - 1)
	{
		psl->a[begin] = psl->a[begin + 1];
		++begin;
	}

	psl->size--;
}

1.删除顺序表中pos位置的值,首先要确保pos位置是存在于数组下标中的,即pos < psl->size;
2.从pos位置开始,将pos位置的后面的数依次往前挪,将pos位置的数覆盖掉,这样就像与将pos位置的数删除掉了。
3.挪动数据时,不能从数组中最后一个数开始往前挪,因为这样的话,pos位置与数组尾部中间的数还没开始挪就被覆盖掉了。

在主函数中调用

TestSeqList5()
{
	SL s;
	SLInit(&s);

	SLPushBack(&s, 3);
	SLPushBack(&s, 6);
	SLPushBack(&s, 9);
	SLPushBack(&s, 12);
	SLPrintf(&s);

	int x = 0;
	scanf("%d", &x);
	int pos = SLFind(&s, x);
	if (pos != -1)
	{
		SeqListErase(&s, pos);
	}
	SLPrintf(&s);

}

int main()
{
	TestSeqList5();
	return 0;
}

打印结果
在这里插入图片描述
1.输入要删除的数,例如9,删除这个数首先要找到这个数在数组中的位置。
2.头删与尾删都可以在接口中直接调用这段代码。

顺序表全部代码
SeqList.h头文件部分:包含了库函数的头文件以及自定义函数的声明

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <Assert.h>
#include <stdbool.h>

静态的顺序表,存储的数据是固定的,N个
//#define N 10
//typedef int SLDataType;
//typedef struct SeqList
//{
//	SLDataType a[N];  //定长数组
//	int size; //存储数据的个数
//}SL;


//动态的顺序表
#define N 10
typedef int SLDataType;
typedef struct SeqList
{
	SLDataType* a;
	int size; //存储数据的个数
	int capacity;  //顺序表的容量
}SL;

//初始化
void SLInit(SL* sl);

//销毁顺序表
void SLDestory(SL* sl);

//打印顺序表
void SLPrintf(SL* psl);

//顺序表判空函数
bool SLEmpty(SL* pSL);

//头插头删 尾插尾删

//尾插
void SLPushBack(SL* psl, SLDataType x);

//头插
void SLPushFront(SL* psl, SLDataType x);

//尾删
void SLPopBack(SL* psl);

//头插
void SLPopFront(SL* psl);

//查找某个数在顺序表中的位置,并且返回它的下标,没有找到就返回-1
int SLFind(SL* psl, SLDataType x);

//顺序表在pos位置插入x
void SeqListInsert(SL* psl, size_t pos, SLDataType x);

//顺序表删除pos位置的值
void SeqListErase(SL* psl, size_t pos);

SeqList.c部分:实现各自定义函数的功能

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"

//初始化函数
void SLInit(SL* psl)
{
	assert(psl);
	psl->a = NULL;
	psl->capacity = psl->size = 0;
}

//销毁函数
void SLDestory(SL* psl)
{
	assert(psl);
	if (psl->a)   //销毁顺序表,要保证顺序表不为空
	{
		free(psl->a);
		psl->a = NULL;
		psl->capacity = psl->size = 0;
	}
}

//判空函数
bool SLEmpty(SL* psl)
{
	assert(psl);
	return psl->size == 0;
}

//打印函数
void SLPrintf(SL* psl)
{
	assert(psl);
	assert(!SLEmpty(psl));
	int i = 0;
	for (i = 0; i < psl->size; i++)
	{
		printf("%d ", psl->a[i]);
	}
	printf("\n");
}

//检查容量
void SLCheckCapacity(SL* psl)
{
	assert(psl);
	if (psl->size == psl->capacity)
	{
		int newCapacity = psl->capacity == 0 ? 4 : psl->capacity * 2;
		SLDataType* tmp = (SLDataType*)realloc(psl->a, newCapacity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			perror("ralloc fail");
			exit(-1);
		}

		psl->a = tmp;
		psl->capacity = newCapacity;
	}
}

//尾插
void SLPushBack(SL* psl, SLDataType x)
{
	assert(psl);
	SLCheckCapacity(psl);
	psl->a[psl->size] = x;
	psl->size++;
	
}

//头插
void SLPushFront(SL* psl, SLDataType x)
{
	assert(psl);
	SLCheckCapacity(psl);

	//挪动数据,从后往前挪
	int end = psl->size - 1;
	while (end >= 0)
	{
		psl->a[end + 1] = psl->a[end];
		--end;
	}

	psl->a[0] = x;
	psl->size++;
}

//尾删
void SLPopBack(SL* psl)
{
	assert(psl);
	assert(!SLEmpty(psl));  //顺序表为空时,不能再删除了
	psl->size--;
}

//头删
void SLPopFront(SL* psl)
{
	assert(psl);
	assert(!SLEmpty(psl));  //顺序表为空时,不能再删除了

	//挪动数据,从前往后挪
	int cur = 0;
	while (cur < psl->size-1)
	{
		psl->a[cur] = psl->a[cur + 1];
		cur++;
	}
	psl->size--;
}


//查找某个数在顺序表中的位置,并且返回它的下标,没有找到就返回-1
int SLFind(SL* psl, SLDataType x)
{
	assert(psl);

	for (int i = 0; i < psl->size; i++)
	{
		if (psl->a[i] == x)
		{
			return i;
		}
	}

	return - 1;
}


//顺序表在pos位置插入x
void SeqListInsert(SL* psl, size_t pos, SLDataType x)
{
	assert(psl);
	assert(pos <= psl->size);  //等于时即是尾插

	SLCheckCapacity(psl);  //检查容量

	挪动数据
	//size_t end = psl->size - 1;
	//while (end >= pos)
	//{
	//	psl->a[end + 1] = psl->a[end];
	//	--end;
	//}

	//挪动数据
	size_t end = psl->size;
	while (end > pos)
	{
		psl->a[end] = psl->a[end - 1];
		--end;
	}

	psl->a[pos] = x;
	++psl->size;
}

//顺序表删除pos位置的值
void SeqListErase(SL* psl, size_t pos)
{
	assert(psl);
	assert(pos < psl->size);

	size_t begin = pos;
	while (begin < psl->size - 1)
	{
		psl->a[begin] = psl->a[begin + 1];
		++begin;
	}

	psl->size--;
}

Test.c部分:主函数放在这,在主函数中调用个函数,在实现各函数时,可以用来测试各函数的功能。

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"  


void TestSeqList1()
{
	SL s;
	SLInit(&s);

	SLPushFront(&s, 8);
	SLPushFront(&s, 6);
	SLPushFront(&s, 5);
	SLPushFront(&s, 4);
	SLPrintf(&s);

	SLPushFront(&s, 12);
	SLPrintf(&s);
}

void TestSeqList2()
{
	SL s;
	SLInit(&s);

	SLPushBack(&s, 3);
	SLPushBack(&s, 6);
	SLPushBack(&s, 9);

	SLPrintf(&s);

	SLPushFront(&s, 8);
	SLPrintf(&s);


	SLPopBack(&s);
	SLPopBack(&s);
	SLPopBack(&s);
	SLPrintf(&s);
	SLPopBack(&s);
	SLPrintf(&s);

	SLPopBack(&s);
}

TestSeqList3()
{
	SL s;
	SLInit(&s);

	SLPushBack(&s, 3);
	SLPushBack(&s, 6);
	SLPushBack(&s, 9);
	SLPushBack(&s, 12);
	SLPushBack(&s, 15);
	SLPushBack(&s, 18);
	SLPrintf(&s);

	int a = SLFind(&s, 6);
	printf("%d\n", a);

}

TestSeqList4()
{
	SL s;
	SLInit(&s);

	SLPushBack(&s, 3);
	SLPushBack(&s, 6);
	SLPushBack(&s, 9);
	SLPushBack(&s, 12);
	SLPrintf(&s);

	int x = 0;
	scanf("%d", &x);
	int pos = SLFind(&s, x);
	if (pos != -1)
	{
		SeqListInsert(&s, pos, x*100);
	}
	SLPrintf(&s);

}

TestSeqList5()
{
	SL s;
	SLInit(&s);

	SLPushBack(&s, 3);
	SLPushBack(&s, 6);
	SLPushBack(&s, 9);
	SLPushBack(&s, 12);
	SLPrintf(&s);

	int x = 0;
	scanf("%d", &x);
	int pos = SLFind(&s, x);
	if (pos != -1)
	{
		SeqListErase(&s, pos);
	}
	SLPrintf(&s);

}

int main()
{
	TestSeqList5();
	return 0;
}

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

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

相关文章

光环:元宇宙概念及生态发展现状与研判——张子良

摘要&#xff1a;文章内容主要来源于光环国际2022年第三届中国科创者大会张子良老师的分享&#xff0c;原分享名称为"元宇宙行业应用实践探索"。讲述了元宇宙的理论知识、元宇宙生态圈及当前发展的情况。提出来看一个概念是否相同可以从引入时间、内容两个方面去界定…

【用python的标准库画出显示实时时间的数码管】

&#x1f935;‍♂️ 个人主页老虎也淘气 个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f44d;&#x1f3fb; 收藏…

Java项目:SSM电影售票管理系统

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 管理员角色包含以下功能&#xff1a; 管理员登陆,管理员用户管理,新闻公告增删改查,电影类型增删改查,影院信息增删改查,电影信息增删改查,订单…

计算机网络学习笔记(II)——应用层

文章目录第二章—应用层2.1、应用层原理网络应用的体系结构客服—服务器&#xff08;C/S&#xff09;体系结构对等体&#xff08;P2P&#xff09;体系结构C/S和P2P体系的混合结构进程通信分布式进程通信需要解决的问题应用层协议Internet传输层提供的服务UDP存在的必要性2.2、W…

【Android插件化框架】插件APK中的动态代理

在 Android 中实现插件化框架&#xff0c;需要解决的问题主要如下&#xff1a; 资源和代码的加载Android 生命周期的管理和组件的注册宿主 APK 和插件 APK 资源引用的冲突解决 下面分析几个目前主流的开源框架 DL 动态加载框架 ( 2014 年底) 是基于代理的方式实现插件框架&…

渗透测试 | APP信息收集

0x00 免责声明 本文仅限于学习讨论与技术知识的分享&#xff0c;不得违反当地国家的法律法规。对于传播、利用文章中提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;本文作者不为此承担任何责任&#xff0c;一旦造成后果请自行承担…

【学习笔记76】认识ajax和ajax的请求

一、认识前后端交互 1、前后端交互 前端向后端发送请求, 索要数据因为前端没有办法存储大量数据, 所以数据都存储在后端当前端需要数据时, 需要向后端发送请求, 得到想要的数据 2、什么是ajax ajax全名async javascript and XML(异步JavaScript和XML)是前后台交互的能⼒&#…

手摸手带你撸一个拖拽效果

目录 前言 准备 创建所需要结构 编写样式 js编写拖拽效果 解释方法 所有代码 结尾 前言 最近看见一个拖拽效果的视频&#xff0c;看好多人评论说跟着敲也没效果&#xff0c;还有就是作者也不回复大家提出的一些疑问&#xff0c;本着知其然必要知其所以然的心理&#xf…

【疯狂世界杯】css 动画实现跳动的足球

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4dd;…

python T检验

T检验通常分为三种&#xff1a;单样本T检验、双样本T检验、配对样本T检验原理可以参考&#xff1a;一文详解t检验本文主要介绍使用python实现T检验的过程&#xff0c;内容主要是参考这篇博文&#xff1a;利用python库stats进行t检验 文章目录一、单样本T检验二、独立样本t检验&…

二、Git本地仓库基本操作——创建Git仓库、提交更新或删除文件

1. 创建本地工作仓库 创建本地工作仓库有两种方法&#xff1a; git init 在本地初始化一个git仓库git clone 直接克隆一个远程的git仓库 方法一&#xff1a; 我们在其中一个目录下&#xff0c;点击鼠标右键&#xff0c;然后启动git bash。输入下面命令&#xff1a; git in…

【实战案例】Python 信用卡欺诈检测其实特简单

当我们在网上购买产品时&#xff0c;很多人喜欢使用信用卡。但信用卡欺诈常常会在身边发生&#xff0c;网络安全正成为我们生活中至关重要的一部分。 为了解决这个问题&#xff0c;我们需要利用机器学习算法构建一个异常行为的识别系统&#xff0c;如果发现可疑&#xff0c;中…

2023最新SSM计算机毕业设计选题大全(附源码+LW)之java高校饭堂管理系统8gmjo

这个选题的话其实有很多的&#xff0c;就看你自己能接受怎么样的&#xff0c;比如可以做网站类、系统类、小程序类、安卓app、大数据类等等&#xff0c;这个也要看你个人能力和技术问题&#xff0c;如果技术小白或者有一点点基础的话建议选择网站类和系统类的&#xff0c;如果有…

微服务框架 SpringCloud微服务架构 10 使用Docker 10.2 镜像命令练习

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 SpringCloud微服务架构 文章目录微服务框架SpringCloud微服务架构10 使用Docker10.2 镜像命令练习10.2.1 练习10 使用Docker 10.2 镜像命令…

Spring boot 自动装配原理

Spring boot 为了解决Bean的复杂配置&#xff0c;引入了自动装配机制&#xff1b;那么什么是自动装配&#xff0c;它的原理又是什么呢&#xff1f;我们先通过以下例子来了解以一下什么是自动装配。 Spring boot 集成 redis 引入依赖包 <dependency><groupId>org…

CTFShow pwn07 (ret2libc-64bit

用ROPgabdet 找到pop rdi地址和ret地址&#xff1a; 来自ctfshow pwn7&#xff1a; 64位程序是需要栈平衡的&#xff0c;而且前六个寄存器用完了才会用栈传参 %rdi&#xff0c;%rsi&#xff0c;%rdx&#xff0c;%rcx&#xff0c;%r8&#xff0c;%r9 用作函数参数&#xff0c;依…

rust编程-rust所有权理解(chapter 4.1)

目录 1. 什么是所有权 1.1 堆与栈 1.2 变量作用域 1.3 String类型 1.4 内存和分配 1.5 变量和数据交互的方式 1.5 所有权和函数 1.6 返回值和作用域 所有权 是Rust独有的特性&#xff0c;该设计开创了编程语言中的先河。所有权使得Rust能保证内存的安全&#xff0c;且不…

游程编码(Run Length Coding)

游程编码游程编码基本介绍示例1示例2游程编码适用的场景游程编码 游程编码&#xff08;Run Length Coding&#xff0c;简称RLC&#xff09;又称游程编码、行程长度编码、变动长度编码 等&#xff0c;是一种统计编码。主要技术是检测重复的比特或字符序列&#xff0c;并用它们的…

亚马逊云科技re:Invent 2022 Ruba Borno主题演讲

2022亚马逊云科技re:Invent全球大会精彩内容应接不暇&#xff0c;亚马逊云科技全球渠道与联盟副总裁Ruba Borno在2022亚马逊云科技re:Invent大会的全球合作伙伴峰会上&#xff0c;为合作伙伴带来一系列全新的合作伙伴创新服务。 云上发展持续加速的当下&#xff0c;上云好比一场…

使用Fiddler对手机App抓包

目录 一、查看 Fiddler 的 ip 地址 二、设置 Fiddler 允许远程连接 三、进行手机端 App 的抓包 3.1.准备工作 3.2.手机设置 3.3.安装根证书 四、可能会遇到的问题 一、查看 Fiddler 的 ip 地址 有两种方法都可以查询到。 第一种方法&#xff1a; 打开 Fiddler&#xff…