顺序表的基本操作以应用

顺序表的基本操作

任务描述
本关任务:要求针对顺序存储的线性表完成四个操作函数,分别实现线性表中数据的插入、删除与查找等功能。

相关知识
为了完成本关任务,你需要掌握:顺序表的基本操作。

顺序表的基本操作
线性表是最基本、最简单、也是最常用的一种数据结构。线性表结构中,数据元素之间通过一对一首尾相接的方式连接起来。具体实现时,线性表可以采用不同的存储策略。下面给出了两种基于顺序存储的线性表实现方案:

 图 1:静态数组数组实现
 图 2:动态数组数组实现
本任务关卡采用第二种动态数组将线性表存储在一片连续空间里,并通过 elem 以及 length 这两个属性元素。组织成为一个结构:

elem: 给出线性表存储空间的起始地址
length: 保存线性表中最后一个元素所在的位置
为了讨论简化,我们假设每个数据元素是一个整数:

typedef int ElementType;// 数据元素的数据类型
该线性表的结构定义如下:

typedef struct LNode {
    ElementType *elem;
    int length;  /* 保存线性表中数据元素个数 */
} SqList;
程序中使用到的常量:

#define MAXSIZE 100 /* MAXSIZE,指明线性表存储空间最多可存储的数据元素个数 */
#define ERROR 0 
对数据元素进行操作处理是一个数据结构的重要组成部分。线性表涉及的主要操作如下:

创建线性表:创建一个最多可存储 MAXSIZE 个数据元素的顺序存储的线性表,并将其初始状态设置为 length=0。如果申请存储空间失败返回 false,否则返回 true;该操作函数具体定义如下,其返回值为 bool 型:
bool MakeEmpty(SqList &L);

释放线性表存储空间:释放 L.elem 所指向的用于存储线性表数据元素的存储空间。该操作函数具体定义如下:
void Free(SqList &L)

判断线性表是否为空:若当前线性表是空表,则返回 true,否则返回 false。该操作函数具体定义如下:
bool IsEmpty(SqList &L)

判断线性表是否已满:若线性表达到最大长度,则返回 true,否则返回 false。该操作函数具体定义如下:
bool IsFull(SqList &L)

在线性表位置 P 插入数据元素 x: 将 X 插入在位置 P(1≤P≤L.legnth) 并返回true。若空间已满,则打印 FULL 并返回 false;如果参数 P 指向非法位置,则打印 ILLEGAL POSITION 并返回 false;该操作函数具体定义如下:
bool Insert( SqList &L, ElementType X, int P )

删除线性表位置 P 处的数据元素: 删除线性表第 P 个数据元素。将位置 P P(1≤P≤L.length) 的元素删除并返回 true。若参数 P 指向非法位置,则打印 POSITION P EMPTY(其中 P 是参数值)并返回 false。该操作函数具体定义如下:
bool Delete( SqList &L, int P )

查找线性表中第一个值为 x 的数据元素的位置: 找到线性表中第一个值为 x 的数据元素所在下标。若找不到则返回 ERROR。该操作函数具体定义如下:
int Find( SqList L, ElementType X )

删除线性表中第一个值为 x 的数据元素: 删除第一个值为 x 的数据元素,返回该数据元素所在位置 [1,L.length]。如果不存在值为 x 的数据元素,则打印“FINDING ERROR X”(其中 X 是参数值)则返回 ERROR。该操作函数具体定义如下: 
int DelValue(SqList &L, ElementType X)

打印线性表: 打印整个线性表。该操作函数具体定义如下:
void Print(SqList &L)

编程要求
根据提示,在右侧编辑器代码文件中的 Begin-End 区间内补充代码,实现 step1/Seqlist.h 中的 Insert、Delete、DelValue 和 Find 四个操作函数,以实现线性表中数据的插入、删除与查找等功能。具体要求如下:

Insert 函数:在线性表位置 P 插入数据元素 x, 将X插入在位置 P(1≤P≤L.length+1) 并返回 true。若空间已满,则打印 FULL 并返回false;如果参数 P 指向非法位置,则打印 ILLEGAL POSITION 并返回 false;

Delete 函数:删除线性表位置 P 处的数据元素,删除线性表第 P 个数据元素。将位置 P P(1≤P≤L.length) 的元素删除并返回 true。若参数 P 指向非法位置,则打印 POSITION P EMPTY(其中 P 是参数值)并返回 false。

Find 函数:查找线性表中第一个值为 x 的数据元素的位置,找到线性表中第一个值为 x 的数据元素所在下标。若找不到则返回 ERROR。

DelValue 函数:删除线性表中第一个值为 x 的数据元素: 删除第一个值为 x 的数据元素,返回该数据元素所在位置 [1,L.length]。如果不存在值为 x 的数据元素,则打印“ FINDING ERROR X ”(其中 X 是参数值)则返回 ERROR。

#include <iostream>
using namespace std;

#define MAXSIZE 100
#define ERROR 0

typedef int ElementType;
typedef struct LNode {
	ElementType *elem;
	int length;  /* 保存线性表中数据元素个数 */
} SqList;

/*顺序表的初始化*/
bool MakeEmpty(SqList &L);
/*释放线性表存储空间:*/
void Free(SqList &L) ;
/* 判断线性表是否为空 */
bool IsEmpty(SqList &L);
/* 判断线性表是否已满*/
bool IsFull(SqList &L);
/* 打印线性表*/
void Print(SqList &L);
/*返回线性表中X第一次出现的位置*/
int Find( SqList L, ElementType X );
/*将X插入在位置P(1≤P≤L.length+1)*/
bool Insert( SqList &L, ElementType X, int P );
/* 删除线性表中第一个值为`x`的数据元素 */
int DeleteValue(SqList &L, ElementType X);
/*将位置P(1≤P≤L.length的元素删除*/
bool Delete( SqList &L, int P ) ;



/*返回线性表中X第一次出现的位置,从1开始。若找不到则返回ERROR;*/
int Find( SqList L, ElementType X ) {

	// 请在这里补充代码,完成本关任务
    /********** Begin *********/
for (int i = 0; i < L.length; i++) {
        if (L.elem[i] == X) {
            return i + 1; // 数组索引从0开始,位置从1开始
        }
    }
    return ERROR;

    /********** End **********/
}
/*将X插入在位置P((1≤P≤L.length+1))并返回true。若空间已满,则打印“FULL”并返回false;
如果参数P指向非法位置,则打印“ILLEGAL POSITION”并返回false;*/
bool Insert( SqList &L, ElementType X, int P ) {
	// 请在这里补充代码,完成本关任务
    /********** Begin *********/
  if (IsFull(L)) {
        cout << "FULL" ;
        return false;
    }
    if (P < 1 || P > L.length + 1) {
        cout << "ILLEGAL POSITION" ;
        return false;
    }
    for (int i = L.length; i >= P; i--) {
        L.elem[i] = L.elem[i - 1];
    }
    L.elem[P - 1] = X;
    L.length++;
    return true;

    /********** End **********/
}
/*将位置P((1≤P≤L.length)的元素删除并返回true。若顺序表是空的,则打印“LIST EMPTY” ,并返回false;
若参数P指向非法位置,则打印“POSITION P EMPTY”(其中P是参数值)并返回false。*/
bool Delete( SqList &L, int P ) {
	// 请在这里补充代码,完成本关任务
    /********** Begin *********/
if (IsEmpty(L)) {
        cout << "LIST EMPTY" ;
        return false;
    }
    if (P < 1 || P > L.length) {
        cout << "POSITION " << P << " EMPTY" ;
        return false;
    }
    for (int i = P; i < L.length; i++) {
        L.elem[i - 1] = L.elem[i];
    }
    L.length--;
    return true;

    /********** End **********/
}
/* 删除线性表中第一个值为`x`的数据元素: 删除第一个值为`x`的数据元素,
返回该数据元素所在位置`[1,L.length]`。如果不存在值为`x`的数据元素,则打印“FINDING ERROR X”(其中X是参数值)则返回`ERROR`。*/


int DeleteValue(SqList &L, ElementType X){	
	// 请在这里补充代码,完成本关任务
    /********** Begin *********/
int pos = Find(L, X);
    if (pos == ERROR) {
        cout << "FINDING ERROR " << X;
        return ERROR;
    }
    Delete(L, pos);
    return pos;

    /********** End **********/
}

两个有序顺序表的归并(不含重复元素)

任务描述
本关任务:已知顺序表 L1,L2 中数据由小到大有序,请用尽可能快的方法将 L1 与 L2 中的数据合并到 L3 中,使数据在 L3 中按升序排列。

注意:本关必读中提及的其他操作已经由平台实现,你只要实现本关任务的 Merge 函数即可。

相关知识
为了完成本关任务,你需要掌握:就地归并两个有序顺序表。

就地归并两个有序顺序表
该方案将线性表存储在一片连续空间里,并通过 data 以及 length 这两个属性元素。组织成为一个结构:

data: 给出线性表存储空间的起始地址
length: 保存线性表中数据元素的个数
为了讨论简化,我们假设每个数据元素是一个整数:

typedef int ElementType;// 数据元素的数据类型
该线性表的结构定义如下:
typedef struct LNode {
    ElementType *data;
    int length; /* 保存线性表中数据元素的个数 */
} SqList;
程序中使用到的常量:
#define MAXSIZE 100 /* MAXSIZE,指明线性表存储空间最多可存储的数据元素个数 */
以下三个函数程序中已经给出,不需要读者完成:
//顺序表初始化
bool MakeEmpty(SqList &L);
//整体建立有序顺序表
void CreateList(SqList &L) ;
//输出顺序表
void Print(SqList L) ;
本关涉及的代码文件 merge.h 中作函数的代码框架如下:
/* 实现将从小到大有序顺序表L1和L2中的数据合并到L3中,使数据在L3中按升序排列,
并不含重复元素。(其中L1和L2是严格地递增)*/
void Merge(SqList L1,SqList L2,SqList &L3) {
    // 请在这里补充代码,完成本关任务
    /********** Begin *********/
    /********** End **********/
}
注意:

已有的两个有序表顺序存储方式进行存储;
归并以后不允许表中有重复元素;
异地归并。
编程要求
根据提示,在右侧编辑器代码文件中的 Begin-End 区间内补充代码,完成函数:
void Merge(SqList L1,SqList L2,SqList &L3)
 Merge 函数:实现将从小到大有序顺序表 L1 和 L2 中的数据合并到 L3 中,使数据在 L3 中按升序排列,并不含重复元素。(其中 L1 和 L2 是严格地递增)。

 

#include <iostream>
using namespace std;
#define MAXSIZE 50000
typedef int ElementType;
typedef struct LNode {
	ElementType *data;
	int length; /* 保存线性表中数据元素的个数 */
} SqList;



/* 实现将从小到大有序顺序表L1和L2中的数据合并到L3中,使数据在L3中按升序排列,
并不含重复元素。(其中L1和L2是严格地递增)*/
void Merge(SqList L1,SqList L2,SqList &L3) {
	// 请在这里补充代码,完成本关任务
    /********** Begin *********/
// 初始化L3
    L3.data = new ElementType[MAXSIZE];
    L3.length = 0;
    
    int i = 0, j = 0, k = 0; // i, j分别是L1和L2的索引,k是L3的索引
    
    // 遍历L1和L2,将较小的元素添加到L3中
    while (i < L1.length && j < L2.length) {
        if (L1.data[i] < L2.data[j]) {
            if (k == 0 || L1.data[i] != L3.data[k - 1]) { // 检查是否重复
                L3.data[k++] = L1.data[i];
            }
            i++;
        } else if (L1.data[i] > L2.data[j]) {
            if (k == 0 || L2.data[j] != L3.data[k - 1]) { // 检查是否重复
                L3.data[k++] = L2.data[j];
            }
            j++;
        } else { // L1.data[i] == L2.data[j]
            if (k == 0 || L1.data[i] != L3.data[k - 1]) { // 检查是否重复
                L3.data[k++] = L1.data[i];
            }
            i++;
            j++;
        }
    }
    
    // 将L1剩余的元素添加到L3中
    while (i < L1.length) {
        if (k == 0 || L1.data[i] != L3.data[k - 1]) { // 检查是否重复
            L3.data[k++] = L1.data[i];
        }
        i++;
    }
    
    // 将L2剩余的元素添加到L3中
    while (j < L2.length) {
        if (k == 0 || L2.data[j] != L3.data[k - 1]) { // 检查是否重复
            L3.data[k++] = L2.data[j];
        }
        j++;
    }
    
    // 设置L3的长度
    L3.length = k;

    /********** End **********/
}
基于 NSFW Model 色情图片识别鉴黄 后面更新视频检测 项目背景: 随着互联网的快速发展,网络上的信息量呈现出爆炸式的增长。然而,互联网上的内容良莠不齐,其中不乏一些不良信息,如色情、暴力等。这些信息对青少年的健康成长和社会风气产生了不良影响。为了净化网络环境,保护青少年免受不良信息的侵害,我国政府加大了对网络内容的监管力度。在此背景下,本项目应运而生,旨在实现对网络图片和视频的自动识别与过滤,助力构建清朗的网络空间。 项目简介: 本项目基于 NSFW(Not Safe For Work)Model,利用深度学习技术对色情图片进行识别与鉴黄。NSFW Model 是一种基于卷积神经网络(CNN)的图像识别模型,通过学习大量的色情图片和非色情图片,能够准确地判断一张图片是否含有色情内容。本项目在 NSFW Model 的基础上,进一步优化了模型结构,提高了识别的准确率和效率。 项目功能: 色情图片识别:用户上传图片后,系统会自动调用 NSFW Model 对图片进行识别,判断图片是否含有色情内容。如果含有色情内容,系统会给出相应的提示,并阻止图片的传播。 视频检测:针对网络视频,本项目采用帧提取技术,将视频分解为一帧帧图片,然后使用 NSFW Model 对这些图片进行识别。如果检测到含有色情内容的图片,系统会给出相应的提示,并阻止视频的传播。 实时监控:本项目可应用于网络直播、短视频平台等场景,实时监控画面内容,一旦检测到含有色情内容的画面,立即进行屏蔽处理,确保网络环境的纯洁。
### 如何在本地部署 NSFW 模型或服务 要在本地环境中成功部署 NSFW(不适宜工作场合内容)检测模型或服务,以下是详细的说明: #### 准备环境 为了确保能够顺利运行模型和服务,需要安装必要的依赖项。这些工具和库包括但不限于以下几类: - **Python 环境**: 推荐使用 Python 3.7 或更高版本。 - **Transformers 库**: 提供加载预训练模型的功能[^1]。 - **PyTorch/TensorFlow**: 支持深度学习框架的计算需求。 - **Pillow (PIL)**: 处理图像文件并将其转换为适合输入模型的形式。 具体命令如下所示: ```bash pip install transformers torch Pillow ``` #### 加载模型与测试 通过 Hugging Face 的 `transformers` 工具包可以直接访问已有的 NSFW 图片分类模型。例如,可以采用名为 `"Falconsai/nsfw_image_detection"` 的公开模型来完成此任务[^1]。 下面是一个简单的代码片段展示如何加载该模型并对单张图片执行预测操作: ```python from PIL import Image from transformers import pipeline def classify_nsfw(image_path): # 打开指定路径下的图片文件 img = Image.open(image_path) # 初始化 image-classification 流水线对象,并指明使用的特定模型名称 classifier = pipeline("image-classification", model="Falconsai/nsfw_image_detection") # 对传入的图片调用流水线方法得到其类别标签及其置信度分数列表形式的结果 result = classifier(img) return result if __name__ == "__main__": test_img_path = "<your_test_image>" output_results = classify_nsfw(test_img_path) print(output_results) ``` 注意替换 `<your_test_image>` 成实际存在的图片绝对或者相对地址字符串值之前再尝试运行以上脚本。 #### 构建 RESTful API 服务 如果希望进一步扩展功能至 Web 应用程序层面,则可考虑利用 Flask/Django 这样的轻量级 web 开发框架构建起支持 HTTP 请求交互的服务端接口。这里给出基于 FastAPI 实现的一个简单例子作为示范用途: ```python import uvicorn from fastapi import FastAPI, File, UploadFile from PIL import Image from io import BytesIO from typing import List from pydantic import BaseModel app = FastAPI() class Prediction(BaseModel): label: str score: float @app.post("/predict/", response_model=List[Prediction]) async def predict(file: UploadFile = File(...)): try: contents = await file.read() pil_image = Image.open(BytesIO(contents)) clf_pipeline = pipeline('image-classification', model='Falconsai/nsfw_image_detection') predictions = clf_pipeline(pil_image) formatted_preds = [{"label": pred['label'], "score": round(pred['score'], 4)} for pred in predictions] return formatted_preds except Exception as e: raise ValueError(f"Error processing uploaded file {e}") if __name__ == '__main__': uvicorn.run(app, host='0.0.0.0', port=8000) ``` 启动服务器之后即可向 `/predict/` 路径发送 POST 请求附带上传待分析的目标图片获取返回结果了。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小狗碎碎念

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值