串(string)是由零个或多个字符组成的有限序列,又名叫字符串。形如s="a,b,c.."。ai(1 ≤ i ≤ n)可以是字母、数字或其他字符,i就是该字符在串中位置。串中的字符数目n称为串的长度,定义中谈到“有限”是指长度n是一个有限的数值。两个字符的串称为空串(null string),它的长度为零,可以直接用双引号“”表示。所谓序列,说明串的相邻字符之间具有前驱后继的关系。
空格串,是只包含空格的串。注意它和空串的区别,空格串是有内容有长度的,而且可以不止一个空格。
子串与主串,串中任意个数的连续字符组成的子序列称为该串的字串,相应地,包含子串的串称为主串。
子串在主串中的位置,就是子串第一个字符在主串中的序号。
typedef struct
{
char data[maxsize];
int len;
}stype;
package bind;
class SqString {
final int MaxSize = 100;
char data[];
int length;
public SqString() {
data = new char[MaxSize];
length = 0;
} // 字符串赋值 char[]
public void StrAssign(char cstr[]) {
int i;
for (i = 0; cstr[i] != '/0'; i++)
data[i] = cstr[i];
length = i; }
// 将串s复制给当前串SqSting
public void StrCopy(SqString s) {
int i;
for (i = 0; i < s.length; i++)
data[i] = s.data[i];
length = i;
}
// 判断串是否相等
public boolean StrEqual(SqString s) {
boolean b = true;
if (s.length != length)
b = false;
else
for (int i = 0; i < length; i++)
if (s.data[i] != data[i]) {
b = false;
break;
}
return b;
}
// 求串长
public int StrLength() {
return length;
}
// 当前串与串s连接
public void Concat(SqString s) {
SqString str = new SqString();
int i;
str.length = length + s.length;
for (i = 0; i < length; i++)
str.data[i] = data[i];
for (i = 0; i < s.length; i++)
str.data[length + i] = s.data[i];
this.StrCopy(str);
}
// 返回串从第i开始之后j个字符组成的子串
public SqString SubStr(int i, int j) {
SqString s = new SqString();
if (i <= 0 || i > length || j < 0 || i + j - 1 > length)
return s;
for (int k = i - 1; k < i + j - 1; k++) {
s.data[s.length++] = data[k];
}
return s;
}
// 在当前串在第i位插入S2
public void InsStr(int i, SqString s2) {
int j;
SqString str = new SqString();
if (i <= 0 || i > s2.length + 1) {
System.out.println("Error:out of index! ");
return;
}
for (j = 0; j < i - 1; j++)
str.data[str.length++] = data[j];
for (j = 0; j < s2.length; j++)
str.data[str.length++] = s2.data[j];
for (j = i - 1; j < length; j++)
str.data[str.length++] = data[j];
this.StrCopy(str);
}
// 删除第i位开始长度为j的子串
public void DelStr(int i, int j) {
int k;
SqString s = new SqString();
if (i <= 0 || i > length || i + j > length + 1) {
System.out.println("Error: out of index!");
return;
}
for (k = 0; k < i - 1; k++)
s.data[s.length++] = data[k];
for (k = i + j - 1; k < length; k++)
s.data[s.length++] = data[k];
this.StrCopy(s);
}
// 用串t代替当前串中第i位开始的j个字符构成的子串
public void RepStr(int i, int j, SqString t) {
this.DelStr(i, j);
this.InsStr(i, t);
}
public void DispStr() {
int i;
if (length > 0) {
for (i = 0; i < length; i++)
System.out.print(data[i] + " ");
System.out.println();
}
}
}
public class MySqString {
public static void main(String args[]) {
char cstr1[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', '/0' };
char cstr2[] = { '1', '2', '3', '4', '5', '6', '7', '/0' };
SqString s1 = new SqString();
s1.StrAssign(cstr1);
System.out.print("s1:");
s1.DispStr();
SqString s2 = new SqString();
s2.StrAssign(cstr2);
System.out.print("s2:");
s2.DispStr();
SqString s3 = new SqString();
s3.StrCopy(s1);
System.out.print("s3=s1/ns3:");
s3.DispStr();
System.out.println("s3.length=" + s3.length);
s3.Concat(s2);
System.out.print("s3=s3+s2:");
s3.DispStr();
System.out.println("s3.length=" + s3.length);
SqString s4 = new SqString();
System.out.println("返回串3从第1开始之后2个字符组成的子串");
s4 = s3.SubStr(1, 2);
s4.DispStr();
System.out.println("在当前串在第i位插入S2");
s4.InsStr(2, s2);
s4.DispStr();
System.out.println("删除第2位开始长度为1的子串");
s4.DelStr(2, 1);
s4.DispStr();
System.out.println("用串s2代替当前串中第2位开始的3个字符构成的子串");
s4.RepStr(2, 3, s2);
s4.DispStr(); }
}}
Typedef struct
{ char *ch; //指针域,指向存放串值的存储空间基址
int length; // 整型域:存放串长
}HString;
//串的链式存储表示
typedef struct{
char ch
LStrNode *next;
}LStrNode,*LString;
链式存储简单操作
#include
#include
#include
/*字符结点*/
struct Node{
char c;
struct Node * next;
};
typedef struct Node * PNode;
/*函数声明*/
PNode createNullLinkedString(void);
int isNullLinkedString(PNode pstr);
int initLinkedString(PNode pstr);
int insertBeforeElement(PNode pstr);
int dtempteElement(PNode pstr);
void printString(PNode pstr);
/*----------创建一个空的字符串---------------*/
PNode createNullLinkedString(){
PNode pstr=(PNode)malloc(sizeof(struct Node));
if(pstr != NULL){
pstr->next=NULL;
pstr->c='-';
printf("创建成功!\n");
}
else{
pstr=NULL;
printf("创建失败!\n");
}
return pstr;
}
/*-----------判断串是否为空----------------*/
int isNullLinkedString(PNode pstr){
if(pstr->next == NULL){
printf("空串!\n");
return 1;
}
else{
printf("非空串!\n");
return 0;
}
}
/*----------初始化一个空字符串-------------*/
int initLinkedString(PNode pstr){
PNode cur = pstr;
if(isNullLinkedString(pstr)){
while(1){
char c;
printf("输入字符(@结束)>>>");
scanf("%c",&c);
getchar();
if(c =='@'){
break;
}
// 申请要插入的结点
PNode temp = (PNode)malloc(sizeof(Node));
temp->next = NULL;
temp->c = c;
if(pstr->next == NULL){
pstr->next = temp;
cur = pstr;
}else{
cur->next->next = temp;
cur = cur->next;
}
}
printf("初始化完毕!\n");
printString(pstr);
return 1;
}else{
printf("初始化失败!\n");
return 0;
}
}
/*-----------在指定字符之前插入字符---------------*/
int insertBeforeElement(PNode pstr,char c,char s){
PNode cur = pstr;
while(cur->next != NULL){
// 找到指定字符
if(cur->next->c == c) {
PNode temp = (PNode)malloc(sizeof(PNode));
temp->c = s;
temp->next = cur->next;
cur->next = temp;
printf("插入成功!\n");
printString(pstr);
return 1;
}
cur = cur->next;
}
printf("未找到指定字符,插入失败\n");
return 0;
}
/*---------删除指定元素----------*/
int deleteElement(PNode pstr,char c){
PNode cur = pstr;
while(cur->next != NULL){
// 找到指定字符
if(cur->next->c == c){
cur->next = cur->next->next;
printf("删除成功!\n");
printString(pstr);
return 1;
}
cur = cur->next;
}
printf("删除失败!\n");
return 0;
}
/*----------打印当前字符串----------*/
void printString(PNode pstr){
PNode cur = pstr;
printf("[");
while(cur->next != NULL){
printf(" %c ",cur->next->c);
cur = cur->next;
}
printf("]");
}
/*-------主控-------*/
int main(void){
PNode pstr= NULL;
printf("\n--------字符串的基本操作---------\n");
char c,s,ch;
int input;
while(1){
printf("\n 1_创建空串\n 2_判断当前是否为空\n 3_初始化空串\n");
printf(" 4_在指定字符之前插入字符\n 5_删除指定字符\n 6_打印串\n");
printf("\n请选择>>>");
scanf("%d",&input);
scanf("%c",&ch);
switch(input){
case 1 :
pstr = createNullLinkedString();
break;
case 2 :
isNullLinkedString(pstr);
break;
case 3 :
initLinkedString(pstr);
break;
case 4 :
printf("请指定字符>>>");
scanf("%c",&c);
getchar();
printf("请输入要插入的字符>>>");
scanf("%c",&s);
insertBeforeElement(pstr,c,s);
break;
case 5 :
printf("请指定字符>>>");
scanf("%c",&s);
deleteElement(pstr,s);
break;
case 6 :
printString(pstr);
break;
default:
printf("输入错误,请重新输入");
break;
}
}
return 0;
}
Data
串中元素仅由一个字符组成,相邻元素具有前驱和后继关系。
Operation
StrAssign(T,*chars):生成一个其值等于字符串常量chars的串T。
strCopy(T,S):串S存在,由串S复制得串T
ClearString(S):串S存在,将串清空
StringEmpty(S):若串S为空,返回true,否则false
StrLength(S):返回串S的元素个数,即串的长度
StrCompare(S,T):若S>T,返回值大于0;若S=T,返回0,若S
串的查找
int Index(String S,String T,int pos)
{
int n,m,i;
String sub;
if(pos > 0)
{
n = StrLength(S);//得到主串S的长度
m = StrLength(T);
i = pos;
while(i <= n-m+1)
{
SubString(sub,S,i,m);//取主串第i个位置,m长度的子串
if(StrCompare(sub,T) != 0)//如果两串不相等
i++;
else //如果相等
return i; //返回i值
}
}
return 0;//若无子串与T相等,返回0
}
int Index(String S,String T,int pos)
{
int i = 0;
int j = 0;
int SLen = 0;
int TLen = 0;
while(s[i] != '\0')//计算S长度
{
SLen++;
}
while(T[i] != '\0')//子串T的长度
{
TLen++;
}
int i = pos;
while(i <= SLen - TLen && j <= TLen)
{
if(S[i] == T[i])
{
i++;
j++;
}
else
{
i = i - j + 1;//匹配失败回到开始的地方的下一个位置
j = 0;//子串回到原来位置
}
}
if(j > TLen)
{
return i - TLen;
}
else
return 0;
}
注:分析一下,最好的情况时什么?那就是一开始就成功,此时时间复杂度为O(1)。 稍差一点,如果像”abcdedgood”中查找”good”。那么时间复杂度就是O(n + m),n为主串长度,m为要匹配的子串长度。根据等概原则,平均是(n + m) / 2次查找,时间复杂度为O(n+m)。那么最坏的情况是什么呢?就是每次不成功的匹配都发生在串T的最后一个字符,比如主串S = 0000000000000000000000000000000000001,而要匹配的子串为T = 0000001。前者是有49个“0”和1个“1”,后者是9个“0”和1个“1”。这样等于前40个位置要循环40 * 10次。知道第41个位置,这里也要匹配10次。