用c语言写一个后缀数组的初始化、插入、删除、查询的代码,包含解释
时间: 2024-10-12 12:15:59 浏览: 47
后缀数组是一种数据结构,用于对字符串的所有后缀进行排序。以下是使用C语言实现后缀数组基础操作的简化示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 后缀数组构造函数,输入为字符串s
void suffix_array(char* s) {
int n = strlen(s);
int* sa = malloc(n * sizeof(int)); // 存储后缀起始位置
// 排序过程,这里采用快速排序的思想,实际应用中可能会更复杂
for (int i = 0; i < n; ++i) {
sa[i] = i;
}
quicksort(sa, 0, n - 1, &compare_suf, s);
// 输出排序后的后缀数组
for (int i = 0; i < n; ++i) {
printf("%d ", sa[i]);
}
}
// 快速排序辅助函数,比较后缀
int compare_suf(int a, int b, char* s) {
return strcmp(s + sa[a], s + sa[b]);
}
// 插入操作,给定新后缀str,将其插入到已排序的后缀数组中并保持顺序
void insert_suffix(char* str) {
char* s = get_string(); // 获取当前字符串,包括原后缀数组和新后缀
int n = strlen(s);
int new_pos = binary_search(sa, n, str, s); // 找到插入位置
// 将新后缀插入到数组并更新sa
memmove(&sa[new_pos + 1], &sa[new_pos], (n - new_pos) * sizeof(int));
sa[new_pos] = n;
quicksort(sa, 0, n, compare_suf, s);
free(s);
}
// 删除操作,移除指定索引的后缀
void delete_suffix(int index) {
if (index >= 0 && index < strlen(s)) {
memmove(&sa[index], &sa[index + 1], (strlen(s) - index - 1) * sizeof(int));
quicksort(sa, 0, strlen(s) - 1, compare_suf, s);
} else {
printf("Invalid index.\n");
}
}
// 查询操作,查找指定后缀首次出现的位置
int query_suffix(const char* target) {
int n = strlen(s);
return binary_search(sa, n, target, s);
}
// 辅助函数:二分查找后缀数组
int binary_search(int* arr, int len, char* target, char* s) {
int left = 0, right = len - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (strcmp(s + arr[mid], target) == 0) return mid;
if (strcmp(s + arr[mid], target) < 0) left = mid + 1;
else right = mid - 1;
}
return -1; // 如果未找到,则返回-1
}
// 辅助函数:获取字符串
char* get_string() {
char* temp = malloc(strlen(s) + strlen(str) + 1);
strcpy(temp, s);
strcat(temp, str);
return temp;
}
int main() {
char* s = "banana"; // 示例字符串
suffix_array(s);
// 插入操作
char* new_str = "apple";
insert_suffix(new_str);
// 删除操作
delete_suffix(4); // 删除"an"
// 查询操作
char* query_target = "ana";
int position = query_suffix(query_target);
printf("查询结果: %d\n", position);
return 0;
}
```
注意这只是一个简单的演示,实际应用中需要处理更多的边界条件和性能优化,例如使用更高效的排序算法(如Timsort)替换快速排序。同时,这个代码片段假设了字符串空间足够大并且只存储了原始字符串,实际操作可能需要额外的数据结构。
阅读全文