数据结构--》探索数据结构中的字符串结构与算法

news2024/11/19 15:35:48

        本文将带你深入了解串的基本概念、表示方法以及串操作的常见算法。通过深入理解串的相关概念和操作,我们将能够更好地应用它们来解决算法问题。

        无论你是初学者还是进阶者,本文将为你提供简单易懂、实用可行的知识点,帮助你更好地掌握串在数据结构和算法中的重要性,进而提升算法解题的能力。接下来让我们开启数据结构与算法的奇妙之旅吧。

目录

串的定义与基本操作

串的存储结构

串的模式匹配算法

串的常见应用


串的定义与基本操作

串(也称字符串)是由零个或多个字符组成的有限序列。在计算机科学中,串通常被定义为一个字符数组,其长度可以是任意的。一般记为  S = 'a_1a_2····a_n'  (n \geq 0)

其中,S是串名,单引号括起来的字符序列是串的值;a_i 可以是字母、数字或其他字符;串中字符的个数n称为串的长度。n = 0 时的串称为空串(用 \Phi 表示)

例如:S = "HelloWorld!"   T = 'iPhone 15 Pro Max'   注意:字符串有的语言用双引号,有的单引号

子串:串中任意个连续的字符组成的子序列。   Eg:‘iPhone’、'Pro M' 是串T的子串

主串:包含子串的串。                                       Eg:T是子串 'iPhone' 的主串

字符在主串中的位置”:字符在串中的序号。     Eg:'1' 在T中的位置是8(第一次出现)位序从1

子串在主串的位置:第一字符在主串的位置。   Eg:'11 Pro' 在T中的位置为8

空串: M = '' ;空格串:N = '    '

串是一种特殊的线性表,数据元素之间呈线性关系:

串的数据对象限定为字符集(如中文字符、英文字符、数字字符、标点字符等),串的基本操作如增删改查等通常以子串为操作对象。串的基本操作如下(以C语言举例,这里仅仅是介绍概念):

StrAssign(&T,chars):赋值操作。把串T赋值为chars。

StrCopy(&T,S):复制操作。由串复制得到串T。

StrEmpty(S):判空操作。若S为空串,则返回TRUE,否则返回FALSE。

StrLength(S):求串长。返回串S的元素个数。

ClearString(&S):清空操作。将S清为空串。

DestroyString(&S):销毁串。将串S销毁(回收存储空间)。

Concat(&T,S1,S2):串联接。用T返回由S1和S2联接而成的新串。

SubString(&Sub,S,pos,len):求子串。用Sub返回串S的第pos个字符起长度为len的子串。

Index(S,T):定位操作。若主串S中存在与串T值相同的子串,则返回它在主串S中第一次出现的位置;否则函数值为0。

StrCompare(S,T):比较操作。若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0。

假设有串 T='' ,S='iPhone 15 Pro Max?',W='Pro'

Eg:执行如下基本操作返回相应的结果如下:

Concat(&T,S,W)后,T='iPhone 15 Pro Max?Pro'

SubString(&T,S,4,6)后,T='one 15'

Index(S,W)后,返回值为11

回顾重点,其主要内容整理成如下内容: 

串的存储结构

串是一种特殊的线性表,我们以什么样的方式实现线性表同样我们也可以用什么样的方式实现串

顺序存储:将一个串中的各个字符按照顺序依次存放在一段连续的存储空间中,称为串的顺序存储,具有随机访问的特点。

串的顺序存储结构通常使用字符数组来实现,每个字符都占据一个数组元素,因此在定义字符数组时需要保证空间足够容纳整个字符串。在C语言中,可以使用以下方式定义一个长度为n的字符数组str,用于存储最长长度为n-1的字符串:

char str[n];

当然字符串的顺序存储结构也可以使用动态数组来实现,这种方法需要在运行时根据字符串的长度动态分配内存空间。

下面是C语言中实现字符串顺序存储的一些基本操作:

#include <stdio.h>
#include <stdlib.h>  //需要include<stdlib.h>库函数

#define MAX_SIZE 1000 //定义字符串最大长度

typedef struct {
    char str[MAX_SIZE];
    int length;
} SeqString;

//初始化串
void InitSeqString(SeqString* S, char* str) {
    int i = 0;
    while (str[i]) {  //统计字符串长度
        ++i;
    }
    S->length = i;
    for (i = 0; i < S->length; ++i) {
        S->str[i] = str[i];
    }
}

//获取串长
int LengthSeqString(SeqString S) {
    return S.length;
}

//获取某个位置的字符
char GetSeqString(SeqString S, int i) {
    if (i < 1 || i > S.length) {  //判断位置是否合法
        printf("Position %d is invalid.\n", i);
        exit(1);
    }
    return S.str[i - 1];
}

//修改某个位置上的字符
void SetSeqString(SeqString* S, int i, char ch) {
    if (i < 1 || i > S->length) {  //判断位置是否合法
        printf("Position %d is invalid.\n", i);
        exit(1);
    }
    S->str[i - 1] = ch;
}

//在某个位置插入字符
void InsertSeqString(SeqString* S, int i, char ch) {
    if (i < 1 || i > S->length + 1) {  //判断位置是否合法
        printf("Position %d is invalid.\n", i);
        exit(1);
    }
    if (S->length >= MAX_SIZE) {  //判断是否越界
        printf("The string is full.\n");
        exit(1);
    }
    for (int j = S->length - 1; j >= i - 1; --j) {  //从后往前依次向后移动字符
        S->str[j + 1] = S->str[j];
    }
    S->str[i - 1] = ch;
    ++S->length;  //串长加1
}

//删除某个位置上的字符
void DeleteSeqString(SeqString* S, int i) {
    if (i < 1 || i > S->length) {  //判断位置是否合法
        printf("Position %d is invalid.\n", i);
        exit(1);
    }
    for (int j = i; j < S->length; ++j) {  //从前往后依次向前移动字符
        S->str[j - 1] = S->str[j];
    }
    --S->length;  //串长减1
}

//清空串
void ClearSeqString(SeqString* S) {
    S->length = 0;
}

//复制串
void CopySeqString(SeqString S, SeqString* T) {
    T->length = S.length;
    for (int i = 0; i < S.length; ++i) {
        T->str[i] = S.str[i];
    }
    T->str[T->length] = '\0';  //在复制后的字符串尾部加上结束符'\0'
}

//连接两个串
void ConcatSeqString(SeqString* S, SeqString T) {
    if (S->length + T.length <= MAX_SIZE) {  //判断是否超出最大长度
        for (int i = 0; i < T.length; ++i) {
            S->str[i + S->length] = T.str[i]; //将T中的字符复制到S末尾
        }
        S->length += T.length;
    } else {
        printf("The new string exceeds the maximum length.\n");
    }
}

//比较两个串是否相等
int CompareSeqString(SeqString S, SeqString T) {
    if (S.length != T.length) {  //如果长度不相等,直接返回0
        return 0;
    }
    for (int i = 0; i < S.length; ++i) {
        if (S.str[i] != T.str[i]) { //如果某个字符不相等,返回0
            return 0;
        }
    }
    return 1;
}

int main() {
    SeqString S, T;
    char str1[] = "Hello World!";
    char str2[] = "This is a test.";
    InitSeqString(&S, str1);
    printf("Length of S: %d\n", LengthSeqString(S));  //13
    printf("Character at position 6 of S: %c\n", GetSeqString(S, 6));  //W
    SetSeqString(&S, 7, 'X');
    printf("Modified string: %s\n", S.str); //Hello WXrld!
    InitSeqString(&T, str2);
    InsertSeqString(&T, 3, 'x');
    printf("Inserted string: %s\n", T.str);  //Thix is a test.
    DeleteSeqString(&S, 6);
    printf("Deleted string: %s\n", S.str); //Hello Xrld!
    CopySeqString(T, &S);
    printf("Copied string: %s\n", S.str); //Thix is a test.
    ConcatSeqString(&S, T);
    printf("Concatenated string: %s\n", S.str); //Thix is a test.Thix is a test.
    ClearSeqString(&S);
    printf("Length of S: %d\n", LengthSeqString(S));  //0
    printf("S and T are%s equal.\n", CompareSeqString(S, T) ? "" : " not"); //S and T are not equal.
    return 0;
}

链式存储: 使用链表的方式存储一个字符串。与顺序存储不同,链式存储可以实现动态分配内存,无需预先确定字符串长度,可以灵活地进行插入、删除等操作。

串的链式存储可以采用单向链表、双向链表或循环链表来实现,每个节点存储一个字符。为方便起见,通常在链表末尾添加一个空字符表示该串结束。对于空串,可以定义一个只包含头结点的链表。

下面是C语言中实现字符串链式存储的一些基本操作:

#include <stdio.h>
#include <stdlib.h>  //需要include<stdlib.h>库函数

typedef struct LNode {
    char data;
    struct LNode *next;
} LNode, *LinkList;

//初始化一个空串
void InitString(LinkList* L) {
    *L = (LinkList)malloc(sizeof(LNode));  //创建头结点
    (*L)->next = NULL;
}

//判断是否为空串
int IsEmpty(LinkList L) {
    return L->next == NULL;
}

//获取串长
int LengthString(LinkList L) {
    int len = 0;
    LNode *p = L->next;
    while (p) {
        ++len;
        p = p->next;
    }
    return len;
}

//获取某个位置的字符
char GetChar(LinkList L, int i) {
    if (i < 1 || i > LengthString(L)) {  //判断位置是否合法
        printf("Position %d is invalid.\n", i);
        exit(1);
    }
    LNode *p = L->next;
    int k = 1;
    while (k < i) {
        p = p->next;
        ++k;
    }
    return p->data;
}

//在某个位置插入字符
void InsertChar(LinkList* L, int i, char ch) {
    if (i < 1 || i > LengthString(*L) + 1) {  //判断位置是否合法
        printf("Position %d is invalid.\n", i);
        exit(1);
    }
    LNode *p = *L, *q;
    int k = 1;
    while (k < i) {
        p = p->next;
        ++k;
    }
    q = (LNode*)malloc(sizeof(LNode));  //创建新结点
    q->data = ch;
    q->next = p->next;
    p->next = q;
}

//删除某个位置上的字符
void DeleteChar(LinkList* L, int i) {
    if (i < 1 || i > LengthString(*L)) {  //判断位置是否合法
        printf("Position %d is invalid.\n", i);
        exit(1);
    }
    LNode *p = *L, *q;
    int k = 1;
    while (k < i) {
        p = p->next;
        ++k;
    }
    q = p->next;
    p->next = q->next;
    free(q);  //释放被删除的结点
}

//清空串
void ClearString(LinkList* L) {
    LNode *p = (*L)->next, *q;
    while (p) {
        q = p->next;
        free(p);  //释放结点内存
        p = q;
    }
    (*L)->next = NULL;
}

//复制串
void CopyString(LinkList S, LinkList* T) {
    LNode *p = S->next, *q, *r;
    *T = (LinkList)malloc(sizeof(LNode));  //创建头结点
    r = *T;
    while (p) {
        q = (LNode*)malloc(sizeof(LNode));  //创建新结点
        q->data = p->data;
        r->next = q;
        r = q;
        p = p->next;
    }
    r->next = NULL;
}

//连接两个串
void ConcatString(LinkList* S, LinkList T) {
    LNode *p = (*S)->next;
    while (p->next) {  //找到S的尾结点
        p = p->next;
    }
    p->next = T->next;  //将T中的结点添加到S末尾
    free(T);  //释放T的头结点
}

//比较两个串是否相等
int CompareString(LinkList S, LinkList T) {
    LNode *p = S->next, *q = T->next;
    while (p && q && p->data == q->data) {  //依次比较两个串中每个字符
        p = p->next;
        q = q->next;
    }
    if (!p && !q) {  //如果两个串长度相等且所有字符相等,返回1
        return 1;
    } else {
        return 0;
    }
}

int main() {
    LinkList S, T;
    InitString(&S);
    printf("Is S empty? %s\n", IsEmpty(S) ? "Yes" : "No");  //Yes
    InsertChar(&S, 1, 'H');
    InsertChar(&S, 2, 'e');
    InsertChar(&S, 3, 'l');
    InsertChar(&S, 4, 'l');
    InsertChar(&S, 5, 'o');
    printf("Length of S: %d\n", LengthString(S));  //5
    printf("Character at position 3 of S: %c\n", GetChar(S, 3));  //l
    DeleteChar(&S, 2);
    printf("Modified string: ");
    for (LNode *p = S->next; p; p = p->next) {
        printf("%c", p->data);
    }
    printf("\n"); //Hello
    InitString(&T);
    InsertChar(&T, 1, 'W');
    InsertChar(&T, 2, 'o');
    InsertChar(&T, 3, 'r');
    InsertChar(&T, 4, 'l');
    InsertChar(&T, 5, 'd');
    printf("Are S and T equal? %s\n", CompareString(S, T) ? "Yes" : "No"); //No
    ClearString(&S);
    printf("Is S empty? %s\n", IsEmpty(S) ? "Yes" : "No"); //Yes
    CopyString(T, &S);
    printf("Copied string: ");
    for (LNode *p = S->next; p; p = p->next) {
        printf("%c", p->data);
    }
    printf("\n"); //World
    ConcatString(&S, T);
    printf("Concatenated string: ");
    for (LNode *p = S->next; p; p = p->next) {
        printf("%c", p->data);
    }
    printf("\n"); //WorldWorld
    return 0;
}

回顾重点,其主要内容整理成如下内容: 

串的模式匹配算法

串的模式匹配算法用于在一个主串中查找某个子串的出现位置或匹配情况。常见的模式匹配算法包括朴素算法(暴力算法)和 KMP算法

朴素算法

原理:从主串的第一个字符开始,逐个比较主串和子串对应位置的字符,若不匹配,则将子串向后移动一位,再进行比较,直到子串完全匹配或主串遍历完毕。

实现方式:使用两个指针分别指向主串和子串,进行逐个比较。

代码示例:

int naiveStringMatch(const string& text, const string& pattern) {
    int n = text.length();
    int m = pattern.length();

    for (int i = 0; i <= n - m; i++) {
        int j;
        for (j = 0; j < m; j++) {
            if (text[i + j] != pattern[j]) {
                break;
            }
        }
        if (j == m) {
            return i;  // 匹配成功,返回子串在主串中的起始位置
        }
    }
    return -1;  // 未找到匹配的子串
}

回顾重点,其主要内容整理成如下内容: 

KMP算法

原理:通过预处理模式串构建部分匹配表,根据部分匹配表中的信息进行跳跃匹配,避免重复比较已经匹配过的字符。

实现方式:使用两个指针分别指向主串和子串,并维护一个部分匹配表。

相关图例如下:

代码示例:

void buildPartialMatchTable(const string& pattern, vector<int>& table) {
    int m = pattern.length();
    table.resize(m);
    table[0] = 0;

    int len = 0;
    int i = 1;
    while (i < m) {
        if (pattern[i] == pattern[len]) {
            len++;
            table[i] = len;
            i++;
        } else {
            if (len > 0) {
                len = table[len - 1];
            } else {
                table[i] = 0;
                i++;
            }
        }
    }
}

int kmpStringMatch(const string& text, const string& pattern) {
    int n = text.length();
    int m = pattern.length();
    vector<int> table;
    buildPartialMatchTable(pattern, table);

    int i = 0;  // 主串的指针
    int j = 0;  // 子串的指针

    while (i < n) {
        if (text[i] == pattern[j]) {
            i++;
            j++;
            if (j == m) {
                return i - j;  // 匹配成功,返回子串在主串中的起始位置
            }
        } else {
            if (j > 0) {
                j = table[j - 1];  // 根据部分匹配表进行跳跃
            } else {
                i++;
            }
        }
    }

    return -1;  // 未找到匹配的子串
}

next数组:在KMP算法中,next数组(也称为部分匹配表)是用于辅助模式串匹配的数据结构。它存储了在模式串中,每个位置的最长相同前缀后缀的长度。在考研的过程中我们也需要根据提供的模式串T来求解出next数组:

接下来我们已google模式串进行举例如何计算出相应的next数组的值:

next[1]第一个字符不匹配时:

next[2]第二个字符不匹配时: 

next[3]第三个字符不匹配时:

next[4]第四个字符不匹配时:

next[5]第五个字符不匹配时:

next[6]第六个字符不匹配时:

使用next数组:在上文我们已经通过手算的方式得出next数组,接下来我们开始对该next数组进行相应的使用,起具体的主串如下,模式串就用我们之前得到next数组的字符串google:

在上面我们给出了具体的主串,这里我们将主串和模式串进行依次的匹配,直到第六个没有匹配成功, 也就是说当j为6的时候匹配失败,所以我们需要令 j = next[j] = 1 (j=6)。所以接下来我们需要令模式串在下面的这个位置开始匹配:

在上面的位置我们还是发现主串和模式串不匹配,而且是在第一个字符情况下,所以这里我们我们的 j = next[1] = 0,如果我们检测到j为0的话就需要i和j都进行++操作,也就是开始匹配下一个字符串:

在上面的主串和模式串对比中我们发现在第五个字符串的时候出现了不同如下:

·所以在保持i不变的情况下,我们需要令 j = next[5] = 2 ,也就是从j为2的时候开始匹配:

到此为止我们发现主串和模式串的所以字符都能匹配, 所以google的模式串就匹配成功了:

优化next数组后的nextval数组:在上文讲解的next数组是有地方可以进行优化的,这里不再讲解其原因,就直接告诉你如何在得知next数组相应值的情况下求出nextval数组:

nextval首位无脑写0

next[2]=1这里我们看到next数组序号2模式串b与序号1 a不等,即nextval[2]=next[2]=1

next[3]=1这里我们看到next数组序号3模式串a与序号1 a相等,即nextval[3]=next[1]=0

next[4]=2这里我们看到next数组序号4模式串b与序号2 b相等,即nextval[4]=next[2]=1

next[5]=3这里我们看到next数组序号5模式串a与序号3 a相等,即nextval[5]=next[3]=0

next[6]=4这里我们看到next数组序号6模式串a与序号4 b不等,即nextval[6]=next[6]=4

串的常见应用

串(String)是由零个或多个字符组成的有限序列,在数据结构中有着广泛的应用。下面是串在数据结构中常见的应用:

  1. 文本处理:串广泛应用于文本编辑、搜索和替换等操作。例如,可以使用串来表示、存储和处理文本文件、文章、代码等。

  2. 数据压缩:在数据压缩算法中,串有着重要的作用。常见的压缩算法如LZW、Huffman编码等利用了串的统计特性,对文本数据进行压缩和解压缩操作。

  3. 数据库系统:在数据库系统中,经常需要处理字符串类型的数据,如存储用户的姓名、地址、电话号码等信息。串的操作如匹配、比较、拼接等在数据库查询和数据处理中非常常见。

  4. 编译器和解释器:在编译器和解释器中,串被广泛用于表示源代码、词法分析、语法分析等。编译器通过对源代码进行分析和处理,将其转化为可执行的机器语言。

  5. 字符串匹配和搜索算法:串的匹配和搜索算法是串应用的核心领域之一。KMP算法、Boyer-Moore算法、正则表达式等算法都是基于串的匹配和搜索操作。

  6. 加密算法:在数据加密和安全领域,串常用于表示和处理密钥、密码、哈希值等信息。加密算法如AES、DES等对字符串进行加密和解密操作。

  7. 网络协议:在网络通信中,串被广泛应用于各种协议的数据传输中,如HTTP、SMTP等。通过串的拼接、分割等操作,实现了数据的可靠传输和通信。

这些只是串在数据结构中的一些常见应用领域,实际上串在计算机科学中的应用非常广泛,几乎涵盖了各个领域。

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

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

相关文章

【云笔记篇】Microsoft OneNote笔记插件推荐OneMore

【云笔记篇】Microsoft OneNote笔记插件推荐OneMore OneMore插件是一款非常强大&#xff0c;多达一百多个扩展功能的OneNote笔记插件&#xff0c;而且免费开源&#xff0c;不断更新的优秀插件—【蘇小沐】 1、实验 【OneMore官网&#xff1a;OneMore - a OneNote add-in (on…

使用idea 中的rest 将 git 合并部分分支代码到主分支

需求&#xff1a;当要将dev的分支中的部分代码合并到test分支时&#xff0c;又不想把dev的全部代码合并到test分支 例如dev分支已经提交了 demo1到4&#xff0c;到想把demo1-3的代码合并到test分支&#xff0c;demo4暂时不合并 可以使用idea的reset 功能满足以上需求 1首先切…

Activity之间数据回传【Android、activity回传、结合实例】

任务要求 在Android应用中&#xff0c;有时需要从一个Activity向另一个Activity传递数据&#xff0c;并在第二个Activity处理后将结果传递回第一个Activity。 这种情况下&#xff0c;我们可以使用startActivityForResult()和onActivityResult()方法来实现数据回传。 实现步骤…

Day-07 修改 Nginx 配置文件

至此&#xff1a; 简单的 Docker 安装 Nginx并启动算是成功了! ps: 如何修改 Nginx的配置、更改nginx 的资源文件&#xff1f; eg&#xff1a; 1、可以将容器中的目录和本机目录做映射。 2、达到修改本机目录文件就影响到容器中的文件。 1.本机创建实例文件夹 新建目录&#x…

图像拼接后丢失数据,转tiff报错rasterfile failed: an unknown

图像拼接后丢失数据 不仅是数据丢失了&#xff0c;还有个未知原因报错 部分数据存在值不存在的情况 原因 处理遥感数据很容易&#xff0c;磁盘爆满了 解决方案 清理一些无用数据&#xff0c;准备买个2T的外接硬盘用着了。 然后重新做处理

获取沪深300的所有个股列表

脚本&#xff1a; import requests from bs4 import BeautifulSoupurl "https://q.stock.sohu.com/cn/bk_4444.shtml" response requests.get(url) soup BeautifulSoup(response.text, "html.parser")# 找到包含class为e1的元素 elements soup.find_a…

计算机毕设 大数据房价预测分析与可视

文章目录 0 前言1 课题背景2 导入相关的数据 3 观察各项主要特征与房屋售价的关系4 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟…

战火使命攻略,高级回响怎么出现

《战火使命》中&#xff0c;高级回响材料是每个玩家追求的梦想&#xff0c;因为它们不仅能够提升角色的实力&#xff0c;还能让你在战场上独具风采。本战火使命攻略将详细介绍三种获取高级回响的方法&#xff0c;助你在游戏中更加强大&#xff01; 关注【娱乐天梯】&#xff0c…

数据结构-图-基础知识

图 图的基本概念图的概念顶点和边有向图和无向图完全图有向完全图无向完全图 邻接顶点顶点的度路径和路径长度简单路径和回路子图生成树 连通图强连通图 图的存储结构邻接矩阵邻接表 图的遍历BFSDFS 图的基本概念 图的概念 &#x1f680;图是由顶点集合及顶点间关系组成的一种…

O(根号n/ln(根号n))时间复杂度内求n的所有因子

O&#xff08;&#xff09;复杂度内求n的所有因子&#xff0c;在2e9数量级比O&#xff08;&#xff09;快10倍左右 先用范围内的质数除n&#xff0c;求出n的分解质因数形式&#xff0c;然后爆搜求出n的所有因子&#xff0c; n范围内的质数大约有个&#xff0c;所以是这个时间…

Spring Framework 黑马程序员-学习笔记

5.spring-核心概念 IoC &#xff1a;控制反转 使用对象时&#xff08;如在service类中调用Dao层的对象&#xff0c;以便使用Dao类中的方法&#xff09;&#xff0c;本来是依靠new一个Dao层的对象来实现&#xff0c;而实现了Ioc思想的Spring为了解耦&#xff0c;将此过程改为&…

Play Beyond:Sui让优秀的游戏变得更好

自问世以来&#xff0c;视频游戏就紧随着文化产业发展。从Pong和Space Invaders的时代到Animal Crossing和Among Us&#xff0c;伟大的游戏总有能力吸引玩家&#xff0c;并推动娱乐产业发展。根据Grand View Research的数据&#xff0c;全球视频游戏市场在2022年估计为2170.6亿…

fastadmin插件 shopro 商城支付配置

1、 2、 注意上图中有添加支付方式链接&#xff0c;可以点击添加&#xff0c;这里添加后立即生效

zkVM设计性能分析

1. 引言 本文主要参考&#xff1a; 2023年9月ZKSummit10 Wei Dai 1k(x) & Terry Chung 1k(x)分享视频 ZK10: Analysis of zkVM Designs - Wei Dai & Terry Chung 当前有各种zkVM&#xff0c;其设计思想各有不同&#xff0c;且各有取舍&#xff0c;本文重点对现有各z…

[C语言】(指针解决)输入数组,最大的与第一个元素交换,最小的与最后一个元素交换,输出数组

代码 下面是使用指针解决的代码示例&#xff1a; #include <stdio.h>void swap(int *a, int *b) {int temp *a;*a *b;*b temp; }int main() {int arr[100], n, max_index 0, min_index 0;printf("Enter the size of the array: ");scanf("%d"…

Maven(项目构建管理工具)

为什么要使用Maven&#xff1f; 传统项目管理状态分析&#xff1a; ①jar包不统一&#xff0c;jar包不兼容&#xff1b; ②工程升级维护过程操作繁琐&#xff1b; ........... Maven(JAVA书写)&#xff1a;管理jar包以及jar之间的依赖关系&#xff0c;完成项目编译&#xff0c;…

【算法】排序——归并排序和计数排序

主页点击直达&#xff1a;个人主页 我的小仓库&#xff1a;代码仓库 C语言偷着笑&#xff1a;C语言专栏 数据结构挨打小记&#xff1a;初阶数据结构专栏 Linux被操作记&#xff1a;Linux专栏 LeetCode刷题掉发记&#xff1a;LeetCode刷题 算法头疼记&#xff1a;算法专栏…

回归预测|GWO-BPNN-Adaboost算法原理及其实现(Matlab)

在上一篇文章中介绍了BPNN-Adaboost算法的原理及其实现&#xff0c;Adaboost算法可以将多个BPNN作为弱分类器进行训练&#xff0c;使其相互补充&#xff0c;集成为具有较强鲁棒性的强分类器。但由于BPNN对于初始权值和阈值的选取具有随机性&#xff0c;这将导致模型精度的不定性…

【易语言】m3u8下载器源码

前阵子接了个下载视频的小单子&#xff0c;部分视频是m3u8链接的&#xff0c;临时弄了个批量下载器&#xff0c;如图&#xff1a; 这东西网上虽然很多&#xff0c;但还是喜欢自己折腾一下&#xff0c;就直接开源了。代码好不好&#xff0c;只看能不能跑。 原理就是调用ffmpeg&a…