习题4
1.名词解释:串、空串、空格串、子串。
解:串是有限的字符序列,从数据结构角度讲,串属于线性结构。与线性表的不同之处在于串的元素是字符。
空串是不含任何字符的串,其长度为0
空格是一个字符,其ASCII码值是32。空格串是由空格组成的串,其长度等于空格的个数。
串中任意连续的若干字符组成的子序列称为该串的子串。
2.已知三个字符串分别为。利用串的基本运算得到结果串为,要求写出得到结果串所用的函数及执行算法。
解:串可看作由以下两部分组成:,设这两部分分别叫串s1s2,要设法从中得到这两部分,然后使用连接操作连接s1s2得到
i=index();//
s1=substr(,i,length()-i+1);//取出串s1
j=index(,);//求串在串中的起始位置,串中后是
s2=substr(,j+3,length()-j-2);//形成串s2
=concat(s1,s2);
3.已知字符串中存放一段英文,写出算法,将其按给定的长度格式化成两端对齐的字符串,其多余的字符存入
解:题目要求将字符串S1拆分成字符串S2S3,要求字符串S2“按给定长度n格式化为两端对齐的字符串”,即长度为n且首尾字符不能为空格字符。算法从左到右扫描字符串S1,到第一个非空格字符,计数到n,第n个拷入字符串S2的字符不能为空格,然后将余下字符复制到字符串S3中。
void format(char *S1,char *S2,char *S3,int n){
      char *p=S1,*q=S2;
      int i=0;
      while(*p!= '\0'&&*p==' ')p++;//滤掉S1左端空格
      if(*p== '\0'){printf("字符串S1为空串或空格串\n");exit(0);}
      while(*p!= '\0'&&i<n){*q=*p;q++;p++;i++;}//字符串S1向字符串S2中复制
      if(*p== '\0'){printf("字符串S1没有%d个有效字符\n",n);exit(0);}
      if(*(--q)== ' '){//若最后一个字符为空格,则需要向后到第一个非空格字符
        p--;//p指针也后退
        while(*p!= '\0'&&*p==' ')p++;//往后查一个非空格字符作为串S2的尾字符
        if(*p== '\0'){printf("S1没有%d个两端对齐的字符串\n",n);exit(0);}
        *q=*p;//字符串S2最后一个非空字符
        *(++q)= '\0';//S2字符串结束标记
      }
      q=S3;p++;//S1串其余部分送字符串S3
      while(*p!= '\0'){*q=*p;q++;p++;}
      *q= '\0';//置串S3结束标记
}
4.假设采用定长顺序存储结构表示串,编写算法,求串的含不同字符的总数和每个字符的个数。
解:typedef struct {
          char ch;
          int num;
}mytype;
void StrAnalyze(SString S){//统计串S中字符的种类和个数
      int i,j;
      char c;
      mytype T[100]; //用结构数组T存储统计结果
      for(i=1;i<=S[0]+1;i++)T[i-1].ch='\0';
      for(i=1;i<=S[0];i++){
        c=S[i];j=0;       
        while(T[j].ch&&T[j].ch!=c)j++; //查当前字符c是否已记录过
        if(T[j].ch) T[j].num++;
        else {T[j].ch=c;T[j].num=1;}
      }//for
      for(j=0;T[j].ch;j++)
        printf("%c:  %d\n",T[j].ch,T[j].num);
}//StrAnalyze
5.假设采用定长顺序存储结构表示串,编写算法,从串中删除所有和串相同的子串。
解:
void SubString_Delete(SString &s,SString t,int &num){//从串s中删除所有与t相同的子串,num为删除次数
      int i,j,k;
      for(i=1;i<=s[0]-t[0]+1;i++){
        for(j=1;j<=t[0]&&s[i+j-1]==t[j];j++);
        if(j>t[0]){//到了与t匹配的子串
            for(k=i;k<=s[0]-t[0];k++)s[k]=s[k+t[0]]; //左移删除
            s[0]-=t[0];num++;
        }
      }//for
}//Delete_SubString
6.编写算法,实现堆存储结构的串的置换操作Replace(&S,T,V)
解:
void HString_Replace(HString &S,HString T,HString V,int & num){//堆结构串上的置换操作,返回置换次数
      int i,j,k,m;
      for(i=0;i<=S.length-T.length;i++){
        for(j=i,k=0;k<T.length&&S.ch[j]==T.ch[k];j++,k++);
        if(k==T.length) { //到了与T匹配的子串:分三种情况处理
            if(T.length==V.length)
                for(m=1;m<=T.length;m++) S.ch[i+m-1]=V.ch[m-1];
//新子串长度与原子串相同时:直接替换
        else if(T.length<V.length) { //新子串长度大于原子串时:先将后部右移
                  for(m=S.length-1;m>=i+T.length;m--)
S.ch[m+V.length-T.length]=S.ch[m];
                  for(m=0;m<V.length;m++)S.ch[i+m]=V.ch[m];
                }
            else{ //新子串长度小于原子串时:先将后部左移
                for(m=i+V.length;m<S.length+V.length-T.length;m++)
                    S.ch[m]=S.ch[m-V.length+T.length];
                for(m=0;m<V.length;m++)S.ch[i+m]=V.ch[m];
            }
            S.length+=V.length-T.length;
            i+=V.length;num++;
        }//if
      }//for
}//HString_Replace
7.编写算法,实现堆存储结构的串基本操作Concat(&S,S1,S2)
解:
void HString_Concat(HString s1,HString s2,HString &t) {//将堆结构表示的串s1s2连接为新串t
      int i,j;
      if(t.ch) free(t.ch);
      t.ch=new char[s1.length+s2.length];
      for(i=1;i<=s1.length;i++) t.ch[i-1]=s1.ch[i-1];
      for(j=1;j<=s2.length;j++,i++) t.ch[i-1]=s2.ch[j-1];
      t.length=s1.length+s2.length;
}//HString_Concat
8字符串长度17模式串长度.假设以块链结构表示串,试编写判别给定字符串是否具有对称性的算法,并要求算法的时间复杂度为
解:
int LString_Palindrome(LString L) {//判断以块链结构存储的串L是否为回文序列,是则返回1,否则返回0
  InitStack(S);
  p=S.head;i=0;k=1; //i指示元素在块中的下标,k指示元素在整个序列中的序号(1开始)
  for(k=1;k<=S.curlen;k++){
    if(k<=S.curlen/2) Push(S,p->ch[i]); //将前半段的字符入串
    else if(k>(S.curlen+1)/2){
      Pop(S,c); //将后半段的字符与栈中的元素相匹配
      if(p->ch[i]!=c) return 0; //失配
    }
    if(++i==CHUNKSIZE) { //转到下一个元素,当为块中最后一个元素时,转到下一块
      p=p->next;
      i=0;
    }
  }//for
  return 1; //成功匹配
}//LString_Palindrome
9.,试分别求出它们的next函数值和nextval函数值。
解:
j
1
2
3
4
5
6
7
S
a
b
c
a
b
a
a
next[j]
0
1
1
1
2
3
2
nextval[j]
0
1
1
0
1
3
2
j
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
T
a
b
c
a
a
b
b
a
b
c
a
b
a
a
c
b
a
c
b
a
next[j]
0
1
1
1
2
2
3
1
2
3
4
5
3
2
2
1
1
2
1
1
nextval[j]
0
1
1
0
2
1
3
0
1
1
0
5
3
2
2
1
0
2
1
0
10.已知主串,模式串,写出模式串的nextval函数值,并由此画出KMP算法匹配的全过程。
解:
j
1
2
3
4
5
6
7
8
9
10
T
a
d
a
b
b
a
d
a
d
a
nextval[j]
0
1
0
2
1
0
1
0
4
0
匹配过程略。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。