赞
踩
定长顺序结构 是类似于线性表的顺序存储结构,使用一组连续的存储单元存储串值的字符序列。
# define MAXSTRLEN 40//用户可以在255以内定义最大串长
typedef unsigned char SString[MAXSTRLEN + 1];//0号单元存放串的长度
串的实际长度可在这个预定义长度范围内随意,超出预定义长度的串则会被舍去,这称之为“截断”。
如上述定义的那样,一下标为0的数组分量存放串的实际长度。
即在串值后加入一个不计入串长的结束标记字符。此时串长是一个隐含值,不变域操作。
//1、生成一个其值等于chars的字符串T bool StrAssign(SString T, char *chars); //2、由串T复制得串S void StrCopy(SString S, SString T); //3、若S为空串,则返回true,否则返回false bool StrEmpty(SString S); //4、字符串长短比较,返回S长度-T长度 int StrCompare(SString S, SString T); //5、返回串S的元素个数 int StrLength(SString S); //6、显示串的值 void Strshow(SString S); //7、串的拼接 S1后接S2,结果在T中。 bool StrConcat1(SString T, SString S1, SString S2); //8、串的拼接 S1后接S2,结果放在S1中 bool StrConcat2(SString S1, SString S2); //9、用Sub返回串S的第pos个字符起(包括pos位置处的字符)长度为len的子串。 bool SubString(SString Sub, SString S, int pos, int len); //10、清空串 void ClearString(SString S); //11、 返回子串T在主串S中的位置。若不存在,则函数值为0,其中,T非空。 int Index1(SString S, SString T); //12、 返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数值为0,其中,T非空,1≤pos≤StrLength(S)。 int Index2(SString S, SString T, int pos); //13、在串S的第pos个字符之前插入串T。完全插入返回true,部分插入返回false bool StrInsert(SString S, int pos, SString T); //14、从串S中删除第pos个字符起长度为len的子串 bool StrDelete(SString S, int pos, int len);
bool StrAssign(SString T, char *chars) { int i; if (strlen(chars) > MAX_STR_LEN)//chars 的长度大于最大长度,返回false return false; else { T[0] = strlen(chars); // 0号单元存放串的长度 for (i = 1; i <= T[0]; i++)//从1号单元开始复制串的内容 { T[i] = *(chars + i - 1);//等价于T[i] = chars[i-1]; } return true; } }
void StrCopy(SString T, SString S)
{
int i;
for (i = 0; i <= S[0]; i++)
T[i] = S[i];
}
//3、若S为空串,则返回true,否则返回false
bool StrEmpty(SString S)
{
if (S[0] == 0)
return true;
else
return false;
}
int StrCompare(SString S, SString T)
{// 初始条件:串S和T存在。
//操作结果:若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0
int i;
for (i = 1; i <= S[0] && i <= T[0]; ++i)
if (S[i] != T[i])
return S[i] - T[i];
return S[0] - T[0];
}
int StrLength(SString S)
{
return S[0];
}
void Strshow(SString S)
{
int i;
for (i = 1; i <= S[0]; i++)//从1号单元开始逐单元输出串中的字符
{
printf(" %c", S[i]);
}
printf("\n");
}
当S1和S2的长度加在一起超出MAX_STR_LEN时,S2会被截断
bool StrConcat1(SString T, SString S1, SString S2) { // 用T返回S1和S2联接而成的新串。若未截断,则返回true,否则false int i; if (S1[0] + S2[0] <= MAX_STR_LEN) { // 未截断 for (i = 1; i <= S1[0]; i++)//先放S[1]到T中 T[i] = S1[i]; for (i = 1; i <= S2[0]; i++)//接着放S[2]到T中 T[S1[0] + i] = S2[i]; T[0] = S1[0] + S2[0]; return true; } else { // 截断S2 for (i = 1; i <= S1[0]; i++)//先放S[1]到T中 T[i] = S1[i]; for (i = 1; i <= MAX_STR_LEN - S1[0]; i++)//关键,若第一个串长度超过MAX_STR_LEN 则条件不成立,这里循环的次数为,S1剩余空间单位数 T[S1[0] + i] = S2[i]; T[0] = MAX_STR_LEN; return false; } }
bool StrConcat2(SString S1, SString S2) { // 用T返回S1和S2联接而成的新串。若未截断,则返回true,否则false int i = 1; int lens1 = S1[0];//保存S1的长度 while (i <= (MAX_STR_LEN - S1[0]) && i<= S2[0])//i小于等于除去S1长度剩余的长度&&i小于S2的长度 { S1[S1[0] + i] = S2[i];//逐字符赋值 i++; } S1[0] = S1[0] + i - 1;//更新S1长度 if ((lens1 + S2[0]) <= MAX_STR_LEN)//判断有没有截断 return true; else return false; }
bool SubString(SString Sub, SString S, int pos, int len)
{
int i;
if (pos<1 || pos>S[0] || len<0 || len>S[0] - pos + 1)//排除pos值不在S长度范围内的值和len值+pos值超出S长度
return false;
for (i = 1; i <= len; i++)
Sub[i] = S[pos + i - 1];//包括pos位置处的字符
Sub[0] = len;
return true;
}
void ClearString(SString S)
{ // 初始条件:串S存在。
//操作结果:将S清为空串
S[0] = 0; // 令串长为零
}
int Index1(SString S, SString T) { int i = 1, j = 1; for ( i = 1; i <=S[0]; i++)//循环主串 { if (S[i]==T[1])//如果在主串中找到一个与子串的第一个字符相等的字符时 { int cont = 1;//计数变量 for ( j = 1; j <=T[0]; j++)//遍历子串 { if (T[j + 1] != S[i + j])//在遍历T[0]时如果有不一致时退出遍历 { break; } else//否则计数 { cont++; if (cont == T[0])//当有T[0]个字符相同时则找到子串位置 return i; } } } continue; } return 0;//不存在时 }
int Index2(SString S, SString T, int pos) { int i, j; if (1 <= pos && pos <= S[0]) { i = pos;//从主串的第pos个字符开始和子串的第一个字符比较 j = 1; while (i <= S[0] && j <= T[0]) { if (S[i] == T[j]) // 若第一个字符比较后相等则继续比较后继字符 { ++i; ++j; } else //若第一个字符不叫后不相等则后移一个位置重新开始匹配 { i = i - j + 2; j = 1; } } if (j > T[0])//条件成立表示子串中的所有字符都能匹配相等,即主串中包含子串 return i - T[0]; else return 0; } else return 0; }
bool StrInsert(SString S, int pos, SString T) { // 初始条件:串S和T存在,1≤pos≤StrLength(S)+1 // 操作结果:在串S的第pos个字符之前插入串T,第pos个位置插入T[1]。完全插入返回true,部分插入返回false int i; if (pos<1 || pos>S[0] + 1)//插入位置不在S长度范围之内 return false; if (S[0] + T[0] <= MAX_STR_LEN) { // 完全插入 for (i = S[0]; i >= pos; i--)//pos之后的元素后移T[0]个长度 S[i + T[0]] = S[i]; for (i = pos; i < pos + T[0]; i++)//插入 S[i] = T[i - pos + 1]; S[0] += T[0];//更新长度 return true; } else { // 部分插入 for (i = MAX_STR_LEN; i >= pos + T[0]; i--)//移动串S中位于pos之后仍在串内的字符,因为(S[0] + T[0] > MAX_STR_LEN)所S串插入T后必满, pos + T[0]是插入元素和pos及pos之前元素所占位置 S[i] = S[i - T[0]]; for (i = pos; i < pos + T[0] && i <= MAX_STR_LEN; i++) S[i] = T[i - pos + 1]; S[0] = MAX_STR_LEN;//S的长度为最大 return false;//部分插入 } }
bool StrDelete(SString S, int pos, int len)
{ // 初始条件:串S存在,1≤pos≤StrLength(S)-len+1
// 操作结果:从串S中删除第pos个字符起长度为len的子串
int i;
if (pos<1 || pos>S[0] - len + 1 || len < 0)//pos和len的值超出范围
return false;
for (i = pos + len; i <= S[0]; i++)//循环删除子串后的所有字符
S[i - len] = S[i];//向前移动len个位置
S[0] -= len;//更新串S的长度
return true;
}
// 串的定长顺序存储结构.cpp #include<string.h> #include<malloc.h> // malloc()等 #include<stdio.h> // EOF(=^Z或F6),NULL #include<stdlib.h> // atoi() #define MAX_STR_LEN 40 // 用户可在255(1个字节)以内定义最大串长 typedef char SString[MAX_STR_LEN + 1]; // 0号单元存放串的长度 // SString是数组,故不需引用类型 //1、生成一个其值等于chars的字符串T bool StrAssign(SString T, char *chars); //2、由串T复制得串S void StrCopy(SString S, SString T); //3、若S为空串,则返回true,否则返回false bool StrEmpty(SString S); //4、字符串长短比较,返回S长度-T长度 int StrCompare(SString S, SString T); //5、返回串S的元素个数 int StrLength(SString S); //6、显示串的值 void Strshow(SString S); //7、串的拼接 S1后接S2,结果在T中。 bool StrConcat1(SString T, SString S1, SString S2); //8、串的拼接 S1后接S2,结果放在S1中 bool StrConcat2(SString S1, SString S2); //9、用Sub返回串S的第pos个字符起(包括pos位置处的字符)长度为len的子串。 bool SubString(SString Sub, SString S, int pos, int len); //10、清空串 void ClearString(SString S); //11、 返回子串T在主串S中的位置。若不存在,则函数值为0,其中,T非空。 int Index1(SString S, SString T); //12、 返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数值为0,其中,T非空,1≤pos≤StrLength(S)。 int Index2(SString S, SString T, int pos); //13、在串S的第pos个字符之前插入串T。完全插入返回true,部分插入返回false bool StrInsert(SString S, int pos, SString T); //14、从串S中删除第pos个字符起长度为len的子串 bool StrDelete(SString S, int pos, int len); int main() { char c[MAX_STR_LEN + 1]; SString T; printf("请输入串T: "); gets_s(c);//接收字符串 printf("输入的字符串为 %s\n", c); printf("输入的字符串长度为 %d\n", strlen(c)); if (!StrAssign(T, c)) { printf("串长超过MAX_STR_LEN(=%d)\n", MAX_STR_LEN); exit(0); } Strshow(T); printf("T长度为 %d\n", StrLength(T)); /// SString S; StrCopy(S, T); Strshow(S); /// if (StrEmpty(S)) { printf("串S为空!\n"); } else { printf("串S不为空!\n"); } printf("比较S和T的长度结果 %d\n", StrCompare(S, T)); SString S1, S2; printf("请输入串s1: "); gets_s(c);//接收字符串 printf("输入的字符串S1为 %s\n", c); printf("输入的字符串S1长度为 %d\n", strlen(c)); StrAssign(S1, c); printf("请输入串s2: "); gets_s(c);//接收字符串 StrAssign(S2, c); printf("输入的字符串S2为 %s\n", c); printf("输入的字符串S2长度为 %d\n", strlen(c)); StrConcat1(T, S1, S2); Strshow(T); StrConcat2(S1, S2); Strshow(S1); printf("字符串S1长度为 %d\n", S1[0]); printf("T在S1中的位置为 %d\n",Index1(S1, S2)); int pos = 3, len = 2; printf("T在S1中的位置为 %d\n",Index2(S1, S2,pos)); StrInsert(S1, pos, T); Strshow(S1); StrDelete(S1, pos,len); Strshow(S1); return 0; } //1、生成一个其值等于chars的字符串T bool StrAssign(SString T, char *chars) { int i; if (strlen(chars) > MAX_STR_LEN)//chars 的长度大于最大长度,返回false return false; else { T[0] = strlen(chars); // 0号单元存放串的长度 for (i = 1; i <= T[0]; i++)//从1号单元开始复制串的内容 { T[i] = *(chars + i - 1);//等价于T[i] = chars[i-1]; } return true; } } //2、由串T复制得串S void StrCopy(SString S, SString T ) { int i; for (i = 0; i <= T[0]; i++) S[i] = T[i]; } //3、若S为空串,则返回true,否则返回false bool StrEmpty(SString S) { if (S[0] == 0) return true; else return false; } //4、字符串长短比较,返回S长度-T长度 int StrCompare(SString S, SString T) {// 初始条件:串S和T存在。 //操作结果:若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0 int i; for (i = 1; i <= S[0] && i <= T[0]; ++i) if (S[i] != T[i]) return S[i] - T[i]; return S[0] - T[0]; } //5、返回串S的元素个数 int StrLength(SString S) { return S[0]; } //6、显示串的值 void Strshow(SString S) { int i; for (i = 1; i <= S[0]; i++)//从1号单元开始逐单元输出串中的字符 { printf(" %c", S[i]); } printf("\n"); } //7、串的拼接 S1后接S2,结果放在T中 bool StrConcat1(SString T, SString S1, SString S2) { // 用T返回S1和S2联接而成的新串。若未截断,则返回true,否则false int i; if (S1[0] + S2[0] <= MAX_STR_LEN) { // 未截断 for (i = 1; i <= S1[0]; i++)//先放S[1]到T中 T[i] = S1[i]; for (i = 1; i <= S2[0]; i++)//接着放S[2]到T中 T[S1[0] + i] = S2[i]; T[0] = S1[0] + S2[0]; return true; } else { // 截断S2 for (i = 1; i <= S1[0]; i++)//先放S[1]到T中 T[i] = S1[i]; for (i = 1; i <= MAX_STR_LEN - S1[0]; i++)//关键,若第一个串长度超过MAX_STR_LEN 则条件不成立 T[S1[0] + i] = S2[i]; T[0] = MAX_STR_LEN; return false; } } //8、串的拼接 S1后接S2,结果放在S1中 bool StrConcat2(SString S1, SString S2) { // 用T返回S1和S2联接而成的新串。若未截断,则返回true,否则false int i = 1; int lens1 = S1[0];//保存S1的长度 while (i <= (MAX_STR_LEN - S1[0]) && i<= S2[0])//i小于等于除去S1长度剩余的长度&&i小于S2的长度 { S1[S1[0] + i] = S2[i];//逐字符赋值 i++; } S1[0] = S1[0] + i - 1;//更新S1长度 if ((lens1 + S2[0]) <= MAX_STR_LEN)//判断有没有截断 return true; else return false; } //9、用Sub返回串S的第pos个字符起(包括pos位置处的字符)长度为len的子串。 bool SubString(SString Sub, SString S, int pos, int len) { int i; if (pos<1 || pos>S[0] || len<0 || len>S[0] - pos + 1)//排除pos值不在S长度范围内的值和len值+pos值超出S长度 return false; for (i = 1; i <= len; i++) Sub[i] = S[pos + i - 1];//包括pos位置处的字符 Sub[0] = len; return true; } //10、清空串 void ClearString(SString S) { // 初始条件:串S存在。 //操作结果:将S清为空串 S[0] = 0; // 令串长为零 } //11、 返回子串T在主串S中的位置。若不存在,则函数值为0,其中,T非空。 int Index1(SString S, SString T) { int i = 1, j = 1; for ( i = 1; i <=S[0]; i++)//循环主串 { if (S[i]==T[1])//如果在主串中找到一个与子串的第一个字符相等的字符时 { int cont = 1;//计数变量 for ( j = 1; j <=T[0]; j++)//遍历子串 { if (T[j + 1] != S[i + j])//在遍历T[0]时如果有不一致时退出遍历 { break; } else//否则计数 { cont++; if (cont == T[0])//当有T[0]个字符相同时则找到子串位置 return i; } } } continue; } return 0;//不存在时 } //12、 返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数值为0,其中,T非空,1≤pos≤StrLength(S)。 int Index2(SString S, SString T, int pos) { int i, j; if (1 <= pos && pos <= S[0]) { i = pos;//从主串的第pos个字符开始和子串的第一个字符比较 j = 1; while (i <= S[0] && j <= T[0]) { if (S[i] == T[j]) // 继续比较后继字符 { ++i; ++j; } else // 指针后退重新开始匹配 { i = i - j + 2; j = 1; } } if (j > T[0]) return i - T[0]; else return 0; } else return 0; } //13、在串S的第pos个字符之前插入串T。完全插入返回true,部分插入返回false bool StrInsert(SString S, int pos, SString T) { // 初始条件:串S和T存在,1≤pos≤StrLength(S)+1 // 操作结果:在串S的第pos个字符之前插入串T,第pos个位置插入T[1]。完全插入返回true,部分插入返回false int i; if (pos<1 || pos>S[0] + 1)//插入位置不在S长度范围之内 return false; if (S[0] + T[0] <= MAX_STR_LEN) { // 完全插入 for (i = S[0]; i >= pos; i--)//pos之后的元素后移T[0]个长度 S[i + T[0]] = S[i]; for (i = pos; i < pos + T[0]; i++)//插入 S[i] = T[i - pos + 1]; S[0] += T[0];//更新长度 return true; } else { // 部分插入 for (i = MAX_STR_LEN; i >= pos + T[0]; i--)//移动串S中位于pos之后仍在串内的字符,因为(S[0] + T[0] > MAX_STR_LEN)所S串插入T后必满, pos + T[0]是插入元素和pos及pos之前元素所占位置 S[i] = S[i - T[0]]; for (i = pos; i < pos + T[0] && i <= MAX_STR_LEN; i++) S[i] = T[i - pos + 1]; S[0] = MAX_STR_LEN;//S的长度为最大 return false;//部分插入 } } //14、从串S中删除第pos个字符起长度为len的子串 bool StrDelete(SString S, int pos, int len) { // 初始条件:串S存在,1≤pos≤StrLength(S)-len+1 // 操作结果:从串S中删除第pos个字符起长度为len的子串 int i; if (pos<1 || pos>S[0] - len + 1 || len < 0)//pos和len的值超出范围 return false; for (i = pos + len; i <= S[0]; i++)//循环删除子串后的所有字符 S[i - len] = S[i];//向前移动len个位置 S[0] -= len;//更新串S的长度 return true; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。