第四章-串

在数据结构中,串(String)是由零个或多个字符组成的有限序列。它是一种基本的数据结构,用于表示和操作文本或字符序列。串可以包含字母、数字、符号和空格等字符,长度可以是任意的。

串是一种线性数据结构,其中字符按照顺序排列。每个字符在串中都有一个唯一的位置,称为索引或下标。通常,索引从0开始,表示串中的第一个字符,依此类推。例如,对于一个包含5个字符的串,索引范围是从0到4。

串的常见操作包括:

1. 获取长度:获取串中字符的数量,通常用于确定循环或迭代的范围。
2. 访问字符:通过索引访问串中的特定字符。
3. 连接:将两个串合并成一个新的串,也称为串的拼接。
4. 截取子串:从原串中提取一个子串,包括指定起始位置和结束位置之间的字符。
5. 比较:比较两个串是否相等或大小关系。
6. 查找:在串中查找指定字符或子串的位置。
7. 替换:将串中的特定字符或子串替换为新的字符或子串。
8. 插入:在串的指定位置插入一个字符或子串。
9. 删除:从串中删除指定位置的字符或子串。

串可以使用不同的数据结构来实现,包括数组、链表和字符数组。具体选择哪种实现方式取决于对串操作的需求和性能要求。

在C语言中,串通常使用字符数组来表示。字符数组是一种连续存储字符的数据结构,可以用于存储和操作串。以下是一些常见的串操作算法和相关的C语言代码示例:

1. 获取串长度:
   - 算法:遍历字符数组,直到遇到字符串结束符'\0',统计字符的数量。
   - 示例代码:

   ```c
   #include <stdio.h>
   
   int stringLength(char str[]) {
       int length = 0;
       while (str[length] != '\0') {
           length++;
       }
       return length;
   }
   
   int main() {
       char myString[] = "Hello, World!";
       int length = stringLength(myString);
       printf("Length: %d\n", length);  // 输出: Length: 13
       return 0;
   }
   ```

2. 比较两个串:
   - 算法:逐个比较两个字符数组中的字符,直到遇到不同的字符或者字符串结束符'\0'。
   - 示例代码:

   ```c
   #include <stdio.h>
   
   int stringCompare(char str1[], char str2[]) {
       int i = 0;
       while (str1[i] == str2[i]) {
           if (str1[i] == '\0') {
               return 0;  // 两个串相等
           }
           i++;
       }
       return str1[i] - str2[i];  // 返回不同字符的差值
   }
   
   int main() {
       char string1[] = "Hello";
       char string2[] = "hello";
       int result = stringCompare(string1, string2);
       if (result == 0) {
           printf("Strings are equal\n");
       } else if (result < 0) {
           printf("String1 is less than String2\n");
       } else {
           printf("String1 is greater than String2\n");
       }
       return 0;
   }
   ```

3. 连接两个串:
   - 算法:将第一个字符数组的字符复制到一个新的字符数组中,然后将第二个字符数组的字符追加到新数组的末尾。
   - 示例代码:

   ```c
   #include <stdio.h>
   
   void stringConcatenate(char str1[], char str2[], char result[]) {
       int i = 0, j = 0;
       while (str1[i] != '\0') {
           result[j] = str1[i];
           i++;
           j++;
       }
       i = 0;
       while (str2[i] != '\0') {
           result[j] = str2[i];
           i++;
           j++;
       }
       result[j] = '\0';  // 添加字符串结束符
   }
   
   int main() {
       char string1[] = "Hello";
       char string2[] = ", World!";
       char result[20];  // 结果数组大小要足够容纳两个串及结束符
       stringConcatenate(string1, string2, result);
       printf("Concatenated string: %s\n", result);  // 输出: Concatenated string: Hello, World!
       return 0;
   }
   ```

4. 截取子串:
   - 算法:从源字符数组中复制指定位置和长度的字符到目标字符数组中。
   - 示例代码:

   ```c
   #include <stdio.h>
   
   void substring(char str[], int start, int length, char result[]) {
       int i, j = 0;
       for (i = start; i < start + length; i++) {
           result[j] = str[i];
           j++;
       }
       result[j] = '\0';  // 添加字符串结束符
   }
   
   int main() {
       char myString[] = "Hello, World!";
       char subString[10];  // 结果数组大小要足够容纳子串及结束符
       substring(myString, 7, 5, subString);
       printf("Substring: %s\n", subString);  // 输出: Substring: World
       return 0;
   }
   ```

这些是一些常见的串操作算法和相应的C语言代码示例。在实际应用中,还可以根据具体需求和场景,进一步扩展和优化这些算法。

以下是带有详细注释的C语言代码示例,展示了生成串的顺序表和链表的基本操作:

使用顺序表(数组)实现:

```c
#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 100

typedef struct {
    char data[MAX_SIZE];  // 存储数据的数组
    int length;           // 当前存储的元素个数
} ArrayList;

// 初始化顺序表
void init(ArrayList* list) {
    list->length = 0;  // 将长度初始化为0
}

// 判断顺序表是否为空
int is_empty(ArrayList* list) {
    return list->length == 0;  // 如果长度为0,表示为空
}

// 获取顺序表的大小(元素个数)
int size(ArrayList* list) {
    return list->length;  // 直接返回长度即可
}

// 在顺序表末尾追加元素
void append(ArrayList* list, char item) {
    if (list->length >= MAX_SIZE) {
        printf("Error: List is full\n");  // 如果顺序表已满,打印错误信息
        return;
    }
    list->data[list->length] = item;  // 将元素存储在末尾位置
    list->length++;  // 长度加1
}

// 在指定位置插入元素
void insert(ArrayList* list, int index, char item) {
    if (index < 0 || index > list->length) {
        printf("Error: Invalid index\n");  // 如果索引无效,打印错误信息
        return;
    }
    if (list->length >= MAX_SIZE) {
        printf("Error: List is full\n");  // 如果顺序表已满,打印错误信息
        return;
    }
    // 从插入位置开始,将元素后移一位
    for (int i = list->length - 1; i >= index; i--) {
        list->data[i + 1] = list->data[i];
    }
    list->data[index] = item;  // 将元素插入到指定位置
    list->length++;  // 长度加1
}

// 删除指定元素
void remove_item(ArrayList* list, char item) {
    int found = 0;  // 标记是否找到要删除的元素
    for (int i = 0; i < list->length; i++) {
        if (list->data[i] == item) {
            found = 1;  // 找到要删除的元素
        }
        if (found) {
            list->data[i] = list->data[i + 1];  // 将后续元素向前移动一位
        }
    }
    if (found) {
        list->length--;  // 长度减1
    }
}

// 获取指定位置的元素值
char get(ArrayList* list, int index) {
    if (index < 0 || index >= list->length) {
        printf("Error: Invalid index\n");  // 如果索引无效,打印错误信息
        return '\0';
    }
    return list->data[index];  // 返回指定位置的元素值
}

// 设置指定位置的元素值
void set(ArrayList* list, int index, char item) {
    if (index < 0 || index >= list->length) {
        printf("Error: Invalid index\n");  // 如果索引无效,打印错误信息
        return;
    }
    list->data[index] = item;  // 设置指定位置的元素值
}
```

使用链表实现:

```c
#include <stdio.h>
#include <stdlib.h>

typedef struct Node {
    char data;           // 存储数据的变量
    struct Node* next;   // 指向下一个节点的指针
} Node;

typedef struct {
    Node* head;  // 头节点指针
} LinkedList;

// 初始化链表
void init(LinkedList* list) {
    list->head = NULL;  // 头节点指针置为空
}

// 判断链表是否为空
int is_empty(LinkedList* list) {
    return list->head == NULL;  // 如果头节点指针为空,表示链表为空
}

// 获取链表的大小(元素个数)
int size(LinkedList* list) {
    int count = 0;
    Node* current = list->head;
    while (current != NULL) {
        count++;
        current = current->next;  // 遍历链表,统计节点个数
    }
    return count;
}

// 在链表末尾追加元素
void append(LinkedList* list, char item) {
    Node* new_node = (Node*)malloc(sizeof(Node));  // 创建新节点
    new_node->data = item;  // 设置节点的数据
    new_node->next = NULL;  // 将节点的指针置为空

    if (list->head == NULL) {
        list->head = new_node;  // 如果链表为空,将新节点设置为头节点
    } else {
        Node* current = list->head;
        while (current->next != NULL) {
            current = current->next;  // 遍历到链表末尾
        }
        current->next = new_node;  // 将新节点链接到末尾节点的后面
    }
}

// 在指定位置插入元素
void insert(LinkedList* list, int index, char item) {
    if (index < 0 || index > size(list)) {
        printf("Error: Invalid index\n");  // 如果索引无效,打印错误信息
        return;
    }
    Node* new_node = (Node*)malloc(sizeof(Node));  // 创建新节点
    new_node->data = item;  // 设置节点的数据

    if (index == 0) {
        new_node->next = list->head;  // 如果要插入的位置是头节点之前,将新节点设置为头节点
        list->head = new_node;
    } else {
        Node* current = list->head;
        for (int i = 0; i < index - 1; i++) {
            current = current->next;  // 遍历到插入位置的前一个节点
        }
        new_node->next = current->next;  // 将新节点链接到当前节点的后面
        current->next = new_node;
    }
}

// 删除指定元素
void remove_item(LinkedList* list, char item) {
    if (list->head == NULL) {
        printf("Error: List is empty\n");  // 如果链表为空,打印错误信息
        return;
    }
    if (list->head->data == item) {
        Node* temp = list->head;
        list->head = list->head->next;  // 如果要删除的元素是头节点,将头节点指针指向下一个节点
        free(temp);  // 释放原头节点的内存
        return;
    }
    Node* current = list->head;
    while (current->next != NULL) {
        if (current->next->data == item) {
            Node* temp = current->next;
            current->next = current->next->next;  // 将当前节点的下一个节点指向下下个节点
            free(temp);  // 释放要删除的节点的内存
            return;
        }
        current = current->next;
    }
}

// 获取指定位置的元素值
char get(LinkedList* list, int index) {
    if (index < 0 || index >= size(list)) {
        printf("Error: Invalid index\n");  // 如果索引无效,打印错误信息
        return '\0';
    }
    Node* current = list->head;
    for (int i = 0; i < index; i++) {
        current = current->next;  // 遍历到指定位置的节点
    }
    return current->data;  // 返回节点的数据
}

// 设置指定位置的元素值
void set(LinkedList* list, int index, char item) {
    if (index < 0 || index >= size(list)) {
        printf("Error: Invalid index\n");  // 如果索引无效,打印错误信息
        return;
    }
    Node* current = list->head;
    for (int i = 0; i < index; i++) {
        current = current->next;  // 遍历到指定位置的节点
    }
    current->data = item;  // 设置节点的数据
}
```

这些代码示例展示了使用C语言实现生成串的顺序表和链表的基本操作,并在每个函数中添加了详细的注释,以便理解每个操作的功能和实现细节。你可以根据需要选择适合的数据结构和代码实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

需要什么私信我

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

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

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

打赏作者

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

抵扣说明:

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

余额充值