单选题

第四章 串

填空题

第四章 串

函数题

6-1 字符串 - 1. 字符串长度* (10 分)
C语言标准函数库中包括 strlen 函数,用于计算字符串的长度。作为练习,我们自己编写一个功能与之相同的函数。

函数原型
// 字符串长度
int StrLen(const char *str);
说明:str为串的起始地址,函数值为字符串的长度(不含结束标记’\0’)。

裁判程序
#include <stdio.h>

// 字符串长度
int StrLen(const char *str);

int main()
{
char a[1024];
int n;
gets(a);
n = StrLen(a);
printf("%d\n", n);
return 0;
}

/* 你提交的代码将被嵌在这里 */
输入样例
abcd
输出样例
4

代码如下

int StrLen(const char *str){
int len = 0;
while(*str++)
    len++;
return len;
}

6-2 字符串 - 2. 字符串复制(赋值)* (10 分)
C语言标准函数库中包括 strcpy 函数,用于字符串复制(赋值)。作为练习,我们自己编写一个功能与之相同的函数。

函数原型
// 字符串复制(赋值)
char* StrCpy(char *dst, const char *src);
说明:src 为源串的起始地址,dst 为目的串起始地址,函数将 src 串复制到 dst 串,函数值为 dst。

裁判程序
#include <stdio.h>

// 字符串复制(赋值)
char* StrCpy(char *dst, const char *src);

int main()
{
char a[1024], b[1024], c[1024];
gets(a);
StrCpy(c, StrCpy(b, a));
puts(a);
puts(b);
puts©;
return 0;
}

/* 你提交的代码将被嵌在这里 */
输入样例
abcd
输出样例
abcd
abcd
abcd

代码如下

char* StrCpy(char *dst, const char *src){
    char *p = dst;
while(*dst++ = *src++);
*dst ='\0';
return p;
}

6-3 字符串 - 3. 字符串联接(复合加赋值)* (10 分)
C语言标准函数库中包括 strcat 函数,用于字符串联接(复合加赋值)。作为练习,我们自己编写一个功能与之相同的函数。

函数原型
// 字符串联接(复合加赋值)
char* StrCat(char *dst, const char *src);
说明:src 为源串的起始地址,dst 为目的串起始地址。函数将 src 串添加到 dst 串末尾,函数值为 dst。

裁判程序
#include <stdio.h>

// 字符串联接(复合加赋值)
char* StrCat(char *dst, const char *src);

int main()
{
char a[1024], b[1024], c[1024];
gets(a);
gets(b);
gets©;
StrCat(a, StrCat(b, c));
puts(a);
puts(b);
puts©;
return 0;
}

/* 你提交的代码将被嵌在这里 */
输入样例
abc
de
f
输出样例
abcdef
def
f

代码如下

char* StrCat(char *dst, const char *src){
int i =0;
for(;dst[i] != '\0';i++);
    int j;
    for(j =0 ;src[j]!='\0';j++ )
        dst[i++] = src[j];
    dst[i] ='\0';
return dst;
}

6-4 字符串 - 4. 比较字符串* (10 分)
C语言标准函数库中包括 strcmp 函数,用于字符串的比较。作为练习,我们自己编写一个功能与之相同的函数。

函数原型
// 比较字符串
int StrCmp(const char *str1, const char *str2);
说明:str1 和 str2 分别为两个字符串的起始地址。按字典排序法,若 str1 串值大于 str2,则函数值为正整数;若 str1 串值小于 str2,则函数值为负整数;若 str1 串值与 str2 相等,则函数值为0。

裁判程序
#include <stdio.h>

// 比较字符串
int StrCmp(const char *str1, const char *str2);

int main()
{
char a[1024], b[1024];
int r;
gets(a);
gets(b);
r = StrCmp(a, b);
puts(!r ? “a = b” : r > 0 ? “a > b” : “a < b”);
return 0;
}

/* 你提交的代码将被嵌在这里 */
输入样例1
stock
stack
输出样例1
a > b
输入样例2
he
her
输出样例2
a < b
输入样例3
bye
bye
输出样例3
a = b

代码如下

int StrCmp(const char *str1, const char *str2){
while(*str1!= '\0' && *str1 == *str2)
{
    str1++;
    str2++;
}
if((*str1-*str2)>0)
    return 1;
else if((*str1-*str2)<0)
    return -1;
else
    return 0;
}

6-5 字符串 - 6. 查找子串(BF算法)* (10 分)
C语言标准函数库中包括 strstr 函数,在主串中查找子串。作为练习,我们自己编写一个功能与之相同的函数。

函数原型
// 查找子串
char* StrStr(const char *txt, const char *pat);
说明:txt 和 pat 分别为主串和子串的起始地址。若查找成功,则函数值为子串在主串中首次出现的起始地址,否则函数值为NULL。

特别地,我们对C语言库函数strstr进行适当修改:若子串为空串,则没有意义,函数值规定为NULL。

裁判程序
#include <stdio.h>

// 查找子串
char* StrStr(const char *txt, const char *pat);

int main()
{
char m[1024], s[1024], *p;
gets(m);
gets(s);
p = StrStr(m, s);
if §
{
printf("%d\n", p - m);
}
else
{
puts(“Null”);
}
return 0;
}

/* 你提交的代码将被嵌在这里 */
输入样例1
This is a pencil
is
输出样例1
2
输入样例2
This is a pencil
be
输出样例2
Null

代码如下

char* StrStr(const char *txt, const char *pat){
    char *t=(char *)txt;
    char *p =(char *)pat;
    int len1= 0;
    int len2 = 0;
while(*txt++)
len1++;
while(*pat++)
    len2++;
    if(len2 <=0 )
        return NULL;
    int i = 0,j=0;
while(i < len1 && j <len2){
    if(t[i] == p[j])
    {
        ++i;
        ++j;
    }
    else{
        j =0;
        i = i - j + 1;
    }
}
if(j >= len2)
    return t+(i-len2);
    return NULL;
}

6-6 插入子串* (10 分)
请编写函数,在目的串中插入源串。

函数原型
// 插入子串
char* StrInsert(char *dst, int index, const char *src);
说明:dst 为指示目的串起始地址的指针,index 为插入位置(下标),src 为指示源串起始地址的指针。函数在目的串 dst 下标 index 处插入源串 src,函数值为 dst。

要求:函数能容错运行。若 index 不正确,则不插入子串。

裁判程序
#include <stdio.h>

// 插入子串
char* StrInsert(char *dst, int index, const char *src);

int main()
{
char a[65536], b[65536];
int i;
gets(a);
scanf("%d%*c", &i);
gets(b);
StrInsert(a, i, b);
puts(a);
return 0;
}

/* 你提交的代码将被嵌在这里 */
输入样例1
abcd
2
ef
输出样例1
abefcd
输入样例2
abcd
4
ef
输出样例2
abcdef
输入样例3
abcd
10
ef
输出样例3
abcd
作者: 李祥
单位: 湖北经济学院
时间限制: 15 ms
内存限制: 64 MB
代码长度限制: 16 KB

代码如下

char* StrStuff(char *dst, int idx, int len, const char *src){
    char *d = dst;
    int len2 = 0;
    while(*d++)
        len2++;
int i =0;
if( idx < 0 || idx > len2)
    dst =dst;
if(len < 0 && idx>=0 )
    dst =dst;
if(len > len2 ){
         dst[idx] = '\0';
         dst =dst;
}
for(i = idx;dst[i]!= '\0';i++){
dst[i] = dst[i+len];
}
dst[i] = '\0';
dst =dst;
    char a[65536];
    int k =0,j=0;
    i =0;
        if(idx > len || idx < 0)
        return dst;
        if(idx == len ){
            for(i = 0 ;src[i] != '\0';i++){
                dst[len+i] = src[i];
            }
            dst[len+i] = '\0';
            return dst;
        }
        else{
        for(i = 0 ;i < idx;i++)
            j++;
        for(i = 0;dst[i] != '\0';i++)
            a[k++] = dst[i];
        for(i = 0 ;src[i] != '\0';i++ )
            dst[j++] = src[i];
            for(i = idx ;i < k;i++)
                dst[j++] = a[i];
          dst[j] = '\0';
        }
return dst;
}

6-7 删除子串* (10 分)
请编写函数,删除子串。

函数原型
// 删除子串
char* StrRemove(char *str, int idx, int len);
说明:str 为指示字符串起始地址的指针,idx 为子串的起始位置(下标),len 为子串的长度。函数删除字符串 str 中从下标 idx 处开始、长度为len 的子串,函数值为str。

要求:函数能容错运行。若 len 值不正确,则自动修正。若 idx 值不正确,则不删除子串。

裁判程序
#include <stdio.h>

// 删除子串
char* StrRemove(char *str, int idx, int len);

int main()
{
char a[1024];
int i, n;
gets(a);
scanf("%d%d", &i, &n);
StrRemove(a, i, n);
puts(a);
return 0;
}

/* 你提交的代码将被嵌在这里 */
输入样例1
abcd
1 2
输出样例1
ad
输入样例2
abcd
1 5 (注:按3处理)
输出样例2
a
输入样例3
abcd
2 -5 (注:按0处理)
输出样例3
abcd
输入样例4
abcd
-1 2
输出样例4
abcd

代码如下

char* StrRemove(char *str, int idx, int len){
    char *s =str;
    int len2 = 0;
    while(*s++)
        len2++;
int i =0;
if( idx < 0 || idx > len2)
    return str;
if(len < 0 && idx>=0 )
    return str;
if(len > len2 ){
         str[idx] = '\0';
         return str;
}
for(i = idx;str[i]!= '\0';i++){
str[i] = str[i+len];
}
str[i] = '\0';
return str;
}

6-8 替换子串* (10 分)
请编写函数,替换子串。

函数原型
// 替换子串
char* StrStuff(char *dst, int idx, int len, const char *src);
说明:dst 为指示目的串起始地址的指针,idx 为待删除子串的起始位置(下标),len 为待删除子串的长度,src 为指示待插入源串的起始地址的指针。函数将目的串 dst 中从下标 idx 处开始、长度为 len 的子串替换为源串 src,函数值为 dst。

要求:函数能容错运行。若 len 不正确,则自动修正。若 idx 不正确,则不作任何处理。

裁判程序
#include <stdio.h>

// 替换子串
char* StrStuff(char *dst, int idx, int len, const char *src);

int main()
{
char a[1024], b[1024];
int i, n;
gets(a);
scanf("%d%d%*c", &i, &n);
gets(b);
StrStuff(a, i, n, b);
puts(a);
return 0;
}

/* 你提交的代码将被嵌在这里 */
输入样例1
abcd
1 2
efg
输出样例1
aefgd
输入样例2
abcd
1 5 (注:按3处理)
efgh
输出样例2
aefgh
输入样例3
abcd
2 -5 (注:按0处理)
efg
输出样例3
abefgcd
输入样例4
abcd
8 3
efg
输出样例4
abcd

代码如下

char* StrStuff(char *dst, int idx, int len, const char *src){
   char *d =dst;
   char *d2 =dst;
    int len2 = 0;
    while(*d++)
        len2++;
int i =0;
    if(len < 0)
        len =0;
if( idx < 0 || idx > len2)
    dst =dst;
if(len > len2-idx ){
         dst[idx] = '\0';
}
for(i = idx;dst[i]!= '\0';i++){
dst[i] = dst[i+len];
}
dst[i] = '\0';
    char a[65536];
    i =0;
    int k =0,j=0;
    int len3 =0;
    while(*d2++)
        len3++;
        if(idx > len3 || idx < 0)
        return dst;
        if(idx == len3 ){
            for(i = 0 ;src[i] != '\0';i++){
                dst[idx+i] = src[i];
            }
            dst[idx+i] = '\0';
            return dst;
        }
        else{
        for(i = 0 ;i < idx;i++)
            j++;
        for(i = 0;dst[i] != '\0';i++)
            a[k++] = dst[i];
        for(i = 0 ;src[i] != '\0';i++ )
            dst[j++] = src[i];
            for(i = idx ;i < k;i++)
                dst[j++] = a[i];
          dst[j] = '\0';
        }
return dst;
}

编程题

7-2 【模板】KMP字符串匹配 (20 分)
给出两个字符串text和pattern,其中pattern为text的子串,求出pattern在text中所有出现的位置。

为了减少骗分的情况,接下来还要输出子串的前缀数组next。

输入格式:
第一行为一个字符串,即为text。

第二行为一个字符串,即为pattern。

输出格式:
若干行,每行包含一个整数,表示pattern在text中出现的位置。

接下来1行,包括length(pattern)个整数,表示前缀数组next[i]的值,数据间以一个空格分隔,行尾无多余空格。

输入样例:
ABABABC
ABA
输出样例:
1
3
0 0 1
样例说明:
第四章 串
代码如下
‘’实现的样例‘’
第四章 串

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int next[1024];
void get_next(char *b,int *next);
int Index_KMP(char *a,char *b,int *next);
int main()
{
    char m[1024],s[1024];
    gets(m);
    gets(s);
   get_next(s,next);
    int result = Index_KMP(m,s,next);
       printf("%d\n",result);
       printf("%d\n",strlen(s));
        for(int i = 0;i < strlen(s)-1;i++)
            printf("%d ",next[i]);
            printf("%d",next[strlen(s)-1]);
            return 0;
}
void get_next(char *b,int *next){
int i = 1,j = 0;
next[0] = 0;
while( i < strlen(b)){
    if(j == 0 || b[i] == b[j]){
        i++;
        j++;
        if(b[i] != b[j])
            next[i] =j;
        else
            next[i] = next[j];
    }
    else
        j = next[j];
}
}
int Index_KMP(char *a,char *b,int *next){
    int i = 0,j=0;
    while(i < strlen(a) && j < strlen(b)){
    if(j == 0 || a[i] == b[j]){
        ++i;
        ++j;
    }
    else
        j = next[j];
    }
    if(j == strlen(b))
        return i-(strlen(b)-1);
    else
        return -1;
}

7-1 接话茬 (25 分)
小CC最喜欢的就是接话茬,别人说一句,小CC就会接着他的话尾巴继续说下去,然后告诉他这是“顶针”修辞手法,活活将人气死。小XX也喜欢接话茬,每天都要与小CC比较技艺。然而无论是谁,都会被他们活活气死,因此两人总是难决胜负。后来小CC和小XX一起上了厦门大学,学习了校选课《接话茬数学原理与杠精的自我修养》,他们决定对两人的接话茬水平进行定量评估。

他们约定比赛规则如下,随机找一个倒霉的路人,路人说一句话,他们一起来接,他们接的话的前缀可以作为路人说的话后缀的长度就是那句话的水平。比如,别人说“abbbaabbc”,小CC接了一句“abbcefagd”,他所说的话的前缀“abbc”正是路人所说的话的后缀,长度为4,那么小CC的水平就是4;如果小XX说的是“xbbcadf”,无法构成路人所说的话的后缀,因此水平只有0。

现在,他们的比赛正式开始,由你来写一个程序充当裁判。

输入格式:
共三行,每行是一句话,长度均不超过10
​6
​​ 。

第一行是路人说的话。第二行是小CC说的话。第三行是小XX说的话。

输出格式:
仅一行,输出小CC和小XX接的话的水平,以空格分割,行末没有多余空格,以换行结束。

输入样例:
abbaabbc
abbc
xbb
输出样例:
4 0

代码如下
第四章 串

#include <stdio.h>

int StrStr(const char *txt, const char *pat);

int main()
{
    char p[1000],CC[1000],XX[1000];
    int r1,r2;
    gets(p);
    gets(CC);
    gets(XX);
    r1 = StrStr(p, CC);
    r2 = StrStr(p, XX);
    printf("%d ", r1);
    printf("%d", r2);
    return 0;
}
int StrStr(const char *txt, const char *pat){
    char *t=(char *)txt;
    char *p =(char *)pat;
    int len1= 0;
    int len2 = 0;
while(*txt++)
len1++;
while(*pat++)
    len2++;
    if(len2 <=0 )
        return NULL;
    int i = 0,j=0;
while(i < len1 && j <len2){
    if(t[i] == p[j])
    {
        ++i;
        ++j;
    }
    else{
        j =0;
        i = i - j + 1;
    }
}
if(j >= len2)
    return j;
    return 0;
}

相关文章: