串的概念
定义
字符串简称串,是一种特殊的线性表,由零个或多个字符组成的有限序列。一般为s=“a1 a2....an” 其中s是串名,用双引号括起来的字符序列为串值,但引号本身并不属于串的内容。ai(1<=i<=n)是一个任意字符,它称为串的元素,是构成串的基本单位,i是它在整个串中的序号;n为串的长度,表示串中所包含的字符个数。
串的循环结构体
typedef struct
{
char* data;
int max;
int len;
}sstring;
运算(概述)与实现
概述:
初始化:申请内存
模式匹配:查找一个字符串中是否存在另一个指定的字符串(即模式)的算法
串比较:指比较两个字符串的大小关系
求串长:输出字符串的长度
串复制:将输入的字符串遍历存储到原字符串中
串联结:先需要找到第一字符串的结束位置,接着把第二字符串元素放到第一字符串后面
输出串:输出字符串的元素
实现:
初始化
/*初始化串*/
int init(sstring *S, int max) {
S->data = (char *) malloc(sizeof(char) * max);
if (!S->data) {
printf("申请内存失败!1000\n");
return 1000;
}
S->max = max;
S->len = 0;
return 0;
}
模式匹配
/*模式匹配*/
int sstrmatch(sstring *S, const char *str) {
int i, j, k;
int m = S->len;
int n = getLength(str);
for (i = 0; i <= m - n; i++) {
j = 0;
k = i;
while (j < n && S->data[k] == str[j]) {
j++;
k++;
}
if (j == n) {
return i+1;
}
}
return -1;
}
串比较
/*比较字符串大小*/
void comparison(sstring *S, sstring *str) {
int sLength = getLength(S->data);
int strLength = getLength(str->data);
if (sLength == strLength) {
int i;
for (i = 0; i < S->len;) {
int sAscll = (int) S->data[i];
int strAscll = (int) str->data[i];
if (sAscll == strAscll) {
i++;
} else if (sAscll > strAscll) {
printf("%s比%s大\n", S->data, str->data);
break;
} else {
printf("%s比%s大\n", str->data, S->data);
break;
}
}
if(i == S->len){
printf("两个字符串相等\n");
}
} else if (sLength > strLength) {
printf("%s比%s大:\n", S->data, str->data);
} else {
printf("%s比%s大:\n", str->data, S->data);
}
}
求串长
/*获取串的长度*/
int getLength(const char *str) {
int length = 0;
while (str[length] != '\0'){
length++;
}
return length;
}
串复制
/*从字符常量拷贝*/
int sstrcpy(sstring *S, char *str) {
int i;
int fromLength = getLength(str);
if (fromLength > S->max) {
printf("超出了字符串S的长度!1001\n");
return 1001;
}
for (i = 0; i < fromLength; i++) {
S->data[i] = str[i];
}
S->data[i] = '\0';
S->len = fromLength;
return 0;
}
串联结
/*联接字符串*/
void addSstring(sstring *S, const char from[]) {
int fromLength = getLength(from);
for (int i = 0; i < fromLength; ++i) {
S->data[S->len + i] = from[i];
}
S->data[S->len + fromLength] = '\0';
S->len += fromLength;
}
输出串
/*输出串*/
void printfS(sstring *S) {
printf("%s\n", S->data);
}
完整Demo
main.c
#include <stdio.h>
#include <stdlib.h>
#include "sstring.c"
#include "welcome.h"
int main() {
sstring S, str;
int cmd, max, index;
str.data = malloc(100);
for (int i = 0; i < getLength(welcome); i++) {
printf("%c", welcome[i]);
for (int m = 0; m < 1000; m++)
for (int n = 0; n < 1000; n++) {
}
}
do {
printf("---------串的储存结构演示-----------\n");
printf("1.初始化串\n");
printf("2.从字符常量拷贝\n");
printf("3.模式匹配\n");
printf("4.比较字符串的大小\n");
printf("5.字符串长度\n");
printf("6.追加字符串\n");
printf("7.输出字符串\n");
scanf("%d", &cmd);
switch (cmd) {
case 1:
printf("请输入串的最大存储值:\n");
scanf("%d", &max);
fflush(stdin);
if (!init(&S, max)) {
printf("初始化串成功!\n");
} else {
printf("初始化串失败!\n");
}
break;
case 2:
printf("请输入拷贝的串:\n");
fflush(stdin); // 清除输入缓冲区中的换行符
scanf(" %[^\n]", str.data); // 加上空格,以消耗掉换行符
if (!sstrcpy(&S, str.data)) {
printf("拷贝成功!\n");
} else {
printf("拷贝失败!\n");
}
break;
case 3:
printf("请输入子串:\n");
scanf(" %[^\n]", str.data);
fflush(stdin);
index = sstrmatch(&S, str.data);
if (index != -1) {
printf("匹配成功,子串在主串的%d位置!\n", index);
} else {
printf("主串中不存在子串:%s\n", str.data);
}
break;
case 4:
printf("请输入比较大小的字符串:");
scanf(" %[^\n]", str.data);
fflush(stdin);
comparison(&S, &str);
break;
case 5:
printf("字符串长度:%d\n", getLength(S.data));
break;
case 6:
printf("请输入追加的字符串:\n");
scanf(" %[^\n]", str.data);
fflush(stdin);
addSstring(&S, str.data);
printf("追加成功!\n");
break;
case 7:
printfS(&S);
break;
case 0:
printf("感谢使用!\n");
break;
default:
printf("输入有误!请重新输入\n");
break;
}
} while (cmd != 0);
free(S.data);
free(str.data);
return 0;
}
sstring.c
/*
sstring.c
*/
#include <stdio.h>
#include "sstring.h"
#include <stdlib.h>
/*初始化串*/
int init(sstring *S, int max) {
S->data = (char *) malloc(sizeof(char) * max);
if (!S->data) {
printf("申请内存失败!1000\n");
return 1000;
}
S->max = max;
S->len = 0;
return 0;
}
/*从字符常量拷贝*/
int sstrcpy(sstring *S, char *str) {
int i;
int fromLength = getLength(str);
if (fromLength > S->max) {
printf("超出了字符串S的长度!1001\n");
return 1001;
}
for (i = 0; i < fromLength; i++) {
S->data[i] = str[i];
}
S->data[i] = '\0';
S->len = fromLength;
return 0;
}
/*模式匹配*/
int sstrmatch(sstring *S, const char *str) {
int i, j, k;
int m = S->len;
int n = getLength(str);
for (i = 0; i <= m - n; i++) {
j = 0;
k = i;
while (j < n && S->data[k] == str[j]) {
j++;
k++;
}
if (j == n) {
return i+1;
}
}
return -1;
}
/*比较字符串大小*/
void comparison(sstring *S, sstring *str) {
int sLength = getLength(S->data);
int strLength = getLength(str->data);
if (sLength == strLength) {
int i;
for (i = 0; i < S->len;) {
int sAscll = (int) S->data[i];
int strAscll = (int) str->data[i];
if (sAscll == strAscll) {
i++;
} else if (sAscll > strAscll) {
printf("%s比%s大\n", S->data, str->data);
break;
} else {
printf("%s比%s大\n", str->data, S->data);
break;
}
}
if(i == S->len){
printf("两个字符串相等\n");
}
} else if (sLength > strLength) {
printf("%s比%s大:\n", S->data, str->data);
} else {
printf("%s比%s大:\n", str->data, S->data);
}
}
/*获取串的长度*/
int getLength(const char *str) {
int length = 0;
while (str[length] != '\0'){
length++;
}
return length;
}
/*联接字符串*/
void addSstring(sstring *S, const char from[]) {
int fromLength = getLength(from);
for (int i = 0; i < fromLength; ++i) {
S->data[S->len + i] = from[i];
}
S->data[S->len + fromLength] = '\0';
S->len += fromLength;
}
/*输出串*/
void printfS(sstring *S) {
printf("%s\n", S->data);
}
sstring.h
/*
sstring.h
顺序字符串
*/
typedef struct
{
char* data;
int max;
int len;
}sstring;
/*初始化串*/
int init(sstring *S, int max);
/*从字符常量拷贝*/
int sstrcpy(sstring *S, char *str);
/*模式匹配*/
int sstrmatch(sstring *S, const char *str);
/*比较字符串大小*/
void comparison(sstring *S, sstring *str);
/*字符串长度*/
int getLength(const char *str);
/*追加*/
void addSstring(sstring *S, const char *from);
/*输出字符串*/
void printfS(sstring *S);
welcome.h
char welcome[] = "DDQ\n"
" = === =\n"
" = == =\n"
" = == =\n"
" = === =\n"
" ==============\n"
" = = = =\n"
" = = = =\n"
" ============\n"
" ==============\n"
" = =\n"
" = =\n"
" =\n"
" = =\n"
" = =\n"
" = =\n"
" = =\n"
;
运行截图
总结
C语言字符串是以字符数组形式存储的,以NULL字符结尾,可以通过指针操作和使用一系列标准库函数来操作。因为串是字符型的线性表,所以线性表的存储方式仍适用于串,也因为字符的特殊性和字符串经常作为一个整体来处理的特点,串在存储时还有一些与一般线性表不同之处