字符串最大子序列,字符串最长长度

  

  你也可以去节目咖啡馆(https://meta.chengxuka.com)打开大学屏题板块,在那里你不仅可以回答,解释,还可以在线回答问题。   

  

     

  

  一、多项选择题   

  

  1.下列程序段的运行结果是()。   

  

  int x5={2,4,6,8,10},*p,* * ppp=x;PP=p;printf('%d ',*(p));printf('%d\n ',* * PP);A.4 4   

  

  B.2 4   

  

  C.2 2   

  

  D.4 6   

  

  甲:乙。   

  

  解析:   

  

  题目中先定义了int类型的数组X,然后定义了两个指针。   

  

  那么p=x,意味着x的基址赋给了p,所以p指向数组中的第一个元素。   

  

  Print *(p)第一次,获取P指向的元素,打印2,然后将指针后移一个位置。   

  

  因为pp=p,意味着P的地址赋给了pp,所以pp指向P,P在最后一次打印后已经被设置回1,所以第二次打印**pp,打印的是4。   

  

  2.对于下列变量定义,正确的赋值是()。   

  

  int *p3,a3;A. p=a   

  

  B.*p=a0   

  

  C.p=a0   

  

  D.p0=a0   

  

  甲:乙。   

  

  解析:   

  

  定义为int *p3,a3;这里可以看出,P是指针数组,P是数组的名字,所以不能作为赋值号的左操作数。所以选项A和C是错的*p,也就是p0,所以选项B相当于P0=A,如上所述,数组P的元素是指针,所以选项D不合适。   

  

  3.下列程序段的输出是()。   

  

  int i,a12={1,2,3,4,5,6,7,8,9,10,11,12},* p4for(I=0;I 4;I){ p=a;}printf('%d\n ',p32);A.12   

  

  B.8   

  

  C6   

  

  D.以上程序存在错误。   

  

  答:答   

  

  解析:   

  

  标题中定义了一维数组a12和指针数组P。   

  

  当i=0时,第一个循环:p0=a0,p0指向a0。   

  

  当i=1时,第二个循环:p1=a3,p1指向a3   

  

  当i=2时,第三个循环:p2=a6,p2指向a6   

  

  当i=3时,第四个循环:p3=a9,p3指向a9。   

  

  当i=4时,循环结束。   

  

  P3 2,相当于p32。因为p32指向a9,p32指向a11,a11对应的值是12,所以输出12。   

  

  4.链表定义如下,值为7的表达式是()。   

  

  struct ST { int n;struct st * next} a3={5,a1,7,a2,9,NULL},* p=a;一个名词   

  

  B.(名词)   

  

  C.p-next-n   

  

  D.结型太阳电池   

  

  答:丙。   

  

  解析:   

  

  *标题中p=a,表示指针P指向a的基址。   

  

  选项A,打印数组A中第一个元素n的值,输出5。   

  

  选项b,也打印5。因为是后来加上的。   

  

  选项C,P指向a的基址,默认情况下,第一个元素p-next表示其下一个元素,分别是7和a2。打印它的N,也就是7。   

  

  选项D,因为-的优先级高于-,所以这里我们取p-n,数组第一个元素的N为5,所以打印6。   

  

  5.在下面的程序段中输入一行字符,按照输入的逆序建立一个链表。   

  

  结构节点{ char info结构节点*链接;} * top,* p;char c;top=NULLwhile ((c=getchar())!=' \ n '){ p=(struct node *)malloc(sizeof(struct node));p-info=c;___________;top=p;}A. top-link=p   

  

  B.p-link=top   

/p>   

C. top=p->link

  

D. p=top->link

  

答:B

  

解析:

  

因为要逆序建立链表,所以让 p->link 赋值为 top,然后 top赋值为 p。

  

二、填空题

  

1.下面程序段的输出结果是( )。

  

const char *s<3> = {"point", "continue", "break"}; for (int i = 2; i >= 0; i--) for (int j = 2; j > i; j--) printf("%s\n", s + j);答:

  

ntinue

  

int

  

oint

  

解析:

  

这里是两层循环嵌套,

  

i=2时,j=2时,内层循环条件不满足。

  

i=1时,j=2时,打印 s+j ,就是 s<1>+2,对应continue,但是因为要加 2,所以从下标为 2 的字符开始,就是 ntinue。

  

j=1时,内层循环条件不满足。

  

i=0时,j=2时,打印 s+j ,就是 s<0>+2,对应point,但是因为要加 2,所以从下标为 2 的字符开始,就是 int。

  

j=1时,打印 s+j ,就是 s<0>+1,对应point,但是因为要加 2,所以从下标为 2 的字符开始,就是o int。

  

2.下面程序段的输出结果是( )。

  

const char *st<> = {"Hello", "world", "!"}, **p = st;p++;printf("%s-%c\n", *p, **p);(*p)++;printf("%s-%c-%c\n", *p, **p, (**p) + 1);答:

  

world-w

  

orld-o-p

  

解析:

  

首先定义了指针数组 st,存储的是 3 个字符串的地址。然后又定义了二级指针变量 p,这里 p 存储的是 st 的基地址。

  

然后 p++,那么指向了里面的第二个字符串的地址。*p 打印该字符串。world,**p,打印字符 w。

  

然后 (*p)++,那么指针向后移动一位,从 o 开始,打印 orld,**p 打印 o,(**p) + 1 先取 **p 就是 o 然后再加 1,就是 p。

  

3.下面程序段的输出结果是( )。

  

static int a<4><4>;int *p<4>, i, j;for (i = 0; i < 4; i++) p = &a<0>;for (i = 0; i < 4; i++){ *(p + i) = 1; *(p + 4 - (i + 1)) = 1;}for (i = 0; i < 4; i++){ for (j = 0; j < 4; j++) printf("%2d", p); printf("\n");}答:

  

1 0 0 1

  

0 1 1 0

  

0 1 1 0

  

1 0 0 1

  

解析:

  

首先定义了一个 4X4 的矩阵,默认都是 0 。

  

0 0 0 0

  

0 0 0 0

  

0 0 0 0

  

0 0 0 0

  

然后又定义了一个指针数组 p。

  

第一个 for 循环中:p<0> 存储 a<0><0> 的地址。p<1> 存储 a<1><0> 的地址。p<2> 存储 a<2><0> 的地址。p<3> 存储 a<3><0> 的地址。

  

第二个 for 循环中:

  

i = 0 时,

  

*(p + i) = 1 ,表示 *(p<0>+0) ,表示 第一行第一个元素修改值为 1。 *(p + 4 - (i + 1)) = 1 ,表示 *(p<0>+3) , 表示第一行第四个元素修改值为 1。

  

i = 1 时,

  

*(p + i) = 1 ,表示 *(p<1>+1) ,表示 第二行第二个元素修改值为 1。 *(p + 4 - (i + 1)) = 1 ,表示 *(p<1>+2) , 表示第二行第三个元素修改值为 1。

  

i = 2 时,

  

*(p + i) = 1 ,表示 *(p<2>+2) ,表示 第三行第三个元素修改值为 1。 *(p + 4 - (i + 1)) = 1 ,表示 *(p<2>+2) , 表示第三行第二个元素修改值为 1。

  

i = 3 时,

  

*(p + i) = 1 ,表示 *(p<3>+3) ,表示 第四行第四个元素修改值为 1。 *(p + 4 - (i + 1)) = 1 ,表示 *(p<3>+0) , 表示第四行第一个元素修改值为 1。

  

第三个 for 循环,打印这个矩阵,所以最终结果为:

  

1 0 0 1

  

0 1 1 0

  

0 1 1 0

  

1 0 0 1

  

4.找出最小字符串。输出多个字符串中最小的字符串。请填空。

  

const char *st<> = {"bag", "good", "This", "are", "zoo", "park"};const char *smin = _________;for (int i = 1; i < 6; i++)if (_________ < 0)smin = st;printf("The min string is %s \n",_________ );答:

  

*st

  

strcmp(st, smin)

  

smin

  

解析:

  

首先定义了一个字符指针数组,想找到里面的最小字符串,首先取第一个字符串赋值给 smin,所以 *smin = *st,然后循环中依次比较字符串大小,strcmp(st, smin) <0 ,那么就取 st 赋给 smin,循环结束后打印 smin 即可。

  

5.查找最高分。输入 n(n<=10)个成绩,查找最高分并输出。请填空。

  

#include <stdio.h>int *GetMax(int score<>, int n);int main(void){int i, n, score<10>, *p;scanf("%d", &n);for (i = 0; i < n; i++)scanf("%d", &score);p = _____________;printf("Max:%d\n", *p);return 0;}int *GetMax(int score<>, int n){int i, temp, pos = 0;temp = score<0>;for (i = 0; i < n; i++)if (score > temp){temp = score;pos = i;}return _____________;}答:

  

GetMax(score, n)

  

score + pos 或者 &score

  

解析:

  

就是定义一个函数,找到数组中的最大值,返回它的地址。所以第一个空调用函数,参数传入数组和 n 的值。第二个空,就是函数中返回结果。数组的本质就是存储数组的基地址,加上 pos 即可。

  

6.输出链表中不及格学生的学号和成绩。已建立学生"英语"课程的成绩链表(成绩存于 score 域中,学号存于 num 域中),下列函数的功能是输出不及格学生的学号和成绩。请填空。

  

void require(struct student *head){struct student *p;if (head != NULL){____________;while (p != NULL){if (____________)printf("%d%.1f\n", p->num, p->score);p = p->next;}}}答:

  

p = head

  

p->score < 60

  

解析:

  

第一个空将 head 赋值给 p,第二个空判断成绩是否及格。

  

三、程序设计题

  

题目1:输出月份英文名:输入月份,输出对应的英文名称。要求用指针数组表示 12 个月的英文名称。例如,输入 5 ,输出 May。试编写相应程序。

  

答案代码:

  

#include <stdio.h>char *getmonth(int n);int main(){// 习题(11.3.1)/*输出月份英文名:输入月份,输出对应的英文名称。要求用指针数组表示 12 个月的英文名称。例如,输入 5 ,输出 May。试编写相应程序。*/char *p;int n;printf("input n:");scanf("%d", &n);p = getmonth(n);if (p == NULL)printf("wrong input!\n");elseprintf("%s\n", p);return 0;}char *getmonth(int n){int month;char *a<12> = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November"};if (n > 0 && n < 13){switch (n){case 1:month = 1;break;case 2:month = 2;break;case 3:month = 3;break;case 4:month = 4;break;case 5:month = 5;break;case 6:month = 6;break;case 7:month = 7;break;case 8:month = 8;break;case 9:month = 9;break;case 10:month = 10;break;case 11:month = 11;break;case 12:month = 12;break;}return a<--month>;}elsereturn 0;}运行结果:

  

  

题目2:查找星期:定义一个指针数组,将下表的星期信息组织起来,输入一个字符串,在表中查找,若存在,输出该字符串在表中的序号,否则输出 -1。试编写相应程序。

  

序号

  

星期

  

0

  

Sunday

  

1

  

Monday

  

2

  

Tuesday

  

3

  

Wednesday

  

4

  

Thurday

  

5

  

Friday

  

6

  

Saturday

  

答案代码:

  

#include <stdio.h>#include <string.h>int main(){// 习题(11.3.2)/*查找星期:定义一个指针数组,将下表的星期信息组织起来,输入一个字符串,在表中查找,若存在,输出该字符串在表中的序号,否则输出 -1。试编写相应程序。*/char *p<> = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};char s<10>;printf("input string:");scanf("%s", s);int i = 0, j = -2;for (i = 0; i < 7; i++){if (!strcmp(p, s)){j = i;break;}}printf("%d\n", j); return 0;}运行结果:

  

  

题目3:计算最长的字符串长度:输入 n(n<10)个字符串,输出其中最长字符串的有效长度。要求自定义函数 int max_ len(char *s<>, int n),用于计算有 n 个无素的指针数组 s 中最长的字符串的长度。试编写相应程序。

  

答案代码:

  

#include <stdio.h>#include <string.h>int max_len(char *s<>, int n);int main(){// 习题(11.3.3)/*计算最长的字符串长度:输入 n(n<10)个字符串,输出其中最长字符串的有效长度。要求自定义函数 int max_ len(char *s< >,int n),用于计算有 n 个无素的指针数组 s 中最长的字符串的长度。试编写相应程序。*/int i, n;char *s<10>;char a<10><10>;printf("input n(n<10):");scanf("%d", &n);printf("input %d string :\n", n);for (i = 0; i < n; i++){scanf("%s", a);s = a;}printf("%d\n", max_len(s, n));return 0;}int max_len(char *s<>, int n){int i, j = 0;for (i = 0; i < n; i++){if (strlen(s) > strlen(s)){j = i;}}return strlen(s);}运行结果:

  

  

题目4:字符串的连接:输入两个字符串,输出连接后的字符串。要求自定义函数 char *streat(char *s, char *t), 将字符串 t 复制到字符串 s 的末端,并且返回字符串 s 的首地址。试编写相应程序。

  

答案代码:

  

#include <stdio.h>char *streat(char *s, char *t);int main(){// 习题(11.3.4)/*字符串的连接:输入两个字符串,输出连接后的字符串。要求自定义函数 char *streat(char *s, char *t), 将字符串 t 复制到字符串 s 的末端,并且返回字符串 s 的首地址。*/char s<80>, t<80>;printf("input 1 string s:");gets(s);printf("input 2 string t:");gets(t);printf("%s\n", streat(s, t));return 0;}char *streat(char *s, char *t){int i = 0;int j = 0;while (s != '\0'){i++;}while (t != '\0'){s = t;i++;j++;}return s;}运行结果:

  

  

题目5:指定位置输出字符串:输入一个字符串后再输入两个字符,输出此字符串中从与第 1 个字符匹配的位置开始到与第 2 个字符匹配的位置结束的所有字符。例如,输入字符串 "program" 与 2 个字符 "r" 和 "g" 后,输出 "rog" 。要求自定义函数 char *match(char *s, char ch1, char ch2) 返回结果字符串的首地址。试编写相应程序。

  

答案代码:

  

#include <stdio.h>#include <string.h>char *match(char *s, char ch1, char ch2);int main(){// 习题(11.3.5)/*指定位置输出字符串:输入一个字符串后再输入两个字符,输出此字符串中从与第 1 个字符匹配的位置开始到与第 2 个字符匹配的位置结束的所有字符。例如,输入字符串 "program" 与 2 个字符 "r" 和 "g" 后,输出 "rog" 。要求自定义函数 char *match(char *s, char ch1, char ch2)返回结果字符串的首地址。*/char s<100>, *p;char ch1, ch2;printf("input string:");scanf("%s", s);getchar();printf("input two char:");scanf("%c %c", &ch1, &ch2);p = match(s, ch1, ch2);if (p != NULL)printf("%s\n", p);elseprintf("Not found!\n");return 0;}char *match(char *s, char ch1, char ch2){char c<100>, *p;int i = 0;int j = 0;int start = -1;int end = -1;int k;while (s != '\0'){if (s == ch1) // 找到起始下标{start = i;}if (s == ch2) //找到结束下标{end = i;break; // 如果找到了,就可以直接结束while循环了。}i++;}if (start >= 0 && start <= end){// 遍历 start到 end的字符k = start;while (k <= end){c = s;k++;j++;}c = '\0';p = c;return p;}else{return NULL;}}运行结果:

  

  

题目6:查找子串:输入两个字符串 s 和 t ,在字符串 s 中查找子串 t ,输出起始位置,若不存在,则输出 -1。要求自定义函数 char *search(char *s, char *t)返回子串 t 的首地址,若未找到,则返回 NULL 。试编写相应程序。

  

答案代码:

  

#include <stdio.h>#include <string.h>char *search(char *s, char *t);int main(){// 习题(11.3.6)/*查找子串:输入两个字符串 s 和 t ,在字符串 s 中查找子串 t ,输出起始位置,若不存在,则输出 -1。要求自定义函数 char *search(char *s, char *t)返回子串 t 的首地址,若未找到,则返回 NULL 。*/char s<100>, t<100>, *p;printf("input string:");scanf("%s", s);printf("input substring:");scanf("%s", t);p = search(s, t);if (p != NULL){printf("%ld\n", p - s);}else{printf("-1\n");}return 0;}char *search(char *s, char *t){int size_t = strlen(t), size_s = strlen(s), T, i, j;char *p = NULL;for (i = 0; i <= (size_s - size_t); i++){p = s + i;T = 1;for (j = 0; j < size_t; j++){if (*p != *(t + j)){T = 0;break;}p++;}if (T == 1)break;}if (T == 0)return NULL;elsereturn s + i;}运行结果:

  

  

题目7:奇数值结点链表:输入若干个正整数(输入 -1 为结束标志)建立一个单向链表,头指针为 L ,将链表 L 中奇数值的结点重新组成个新的链表 NEW ,并输出新建链表的信息。试编写相应程序。

  

答案代码:

  

#include <stdio.h>#include <stdlib.h>struct ListNode{int data;struct ListNode *next;};struct ListNode *readlist();struct ListNode *getodd(struct ListNode **L);void printlist(struct ListNode *L);int main(){// 习题(11.3.7)/*奇数值结点链表:输入若干个正整数(输入 -1 为结束标志)建立一个单向链表,头指针为 L ,将链表 L 中奇数值的结点重新组成个新的链表 NEW ,并输出新建链表的信息。*/struct ListNode *L, *Odd;L = readlist();Odd = getodd(&L);printlist(Odd);printlist(L);return 0;}void printlist(struct ListNode *L){struct ListNode *p = L;while (p){printf("%d ", p->data);p = p->next;}printf("\n");}struct ListNode *readlist(){int data;// 输入数据int size = sizeof(struct ListNode); // 单个链表结点占据的内存struct ListNode *head, *tail, *p;head = tail = NULL;printf("input number:");scanf("%d", &data);while (data != -1){p = (struct ListNode *)malloc(size);p->data = data;p->next = NULL;if (head == NULL){head = p;}else{tail->next = p;}tail = p;scanf("%d", &data);}return head;}struct ListNode *getodd(struct ListNode **L){int data;int size = sizeof(struct ListNode);struct ListNode *head, *tail, *pNew; // 链表Newstruct ListNode *ptr1, *ptr2;head = tail = NULL;// L链表的head是奇数while (*L != NULL && (*L)->data % 2 != 0){data = (*L)->data;// 将L链表的奇数重新组成一个新的链表pNew = (struct ListNode *)malloc(size);pNew->data = data;pNew->next = NULL;if (head == NULL){head = pNew;}else{tail->next = pNew;}tail = pNew;// 删除L链表的奇数ptr2 = *L;*L = (*L)->next;free(ptr2);}if (*L == NULL){return NULL;}// L链表的head非奇数ptr1 = *L;ptr2 = (*L)->next;while (ptr2 != NULL){data = ptr2->data;if (data % 2 != 0){// 将L链表的奇数重新组成一个新的链表pNew = (struct ListNode *)malloc(size);pNew->data = data;pNew->next = NULL;if (head == NULL){head = pNew;}else{tail->next = pNew;}tail = pNew;// 删除L链表的奇数ptr1->next = ptr2->next;free(ptr2);}else{ptr1 = ptr2;}ptr2 = ptr1->next;}return head;}运行结果:

  

  

题目8:删除结点:输入若干个正整数(输入 -1 为结束标志)建立一个单向链表,再输入一个整数 m ,删除链表中值为 m 的所有结点。试编写相应程序。

  

答案代码:

  

#include <stdio.h>#include <stdlib.h>struct ListNode{int data;struct ListNode *next;};struct ListNode *readlist();struct ListNode *deletem(struct ListNode *L, int m);void printlist(struct ListNode *L);int main(){// 习题(11.3.8)/*删除结点:输入若干个正整数(输入 -1 为结束标志)建立一个单向链表,再输入一个整数 m ,删除链表中值为 m 的所有结点。*/int m;struct ListNode *L = readlist();printf("input m:");scanf("%d", &m);L = deletem(L, m);printlist(L);return 0;}void printlist(struct ListNode *L){struct ListNode *p = L;while (p){printf("%d ", p->data);p = p->next;}printf("\n");}struct ListNode *readlist(){int data;int size = sizeof(struct ListNode);struct ListNode *head, *tail, *p;head = tail = NULL;printf("input number:");scanf("%d", &data);while (data != -1){p = (struct ListNode *)malloc(size);p->data = data;p->next = NULL;if (head == NULL){head = p;}else{tail->next = p;}tail = p;scanf("%d", &data);}return head;}struct ListNode *deletem(struct ListNode *L, int m){struct ListNode *ptr1, *ptr2;//要被删除结点为表头结点while (L != NULL && L->data == m){ptr2 = L;L = L->next;free(ptr2);}// 链表空if (L == NULL){return NULL;}// 要被删除结点为非表头结点ptr1 = L;ptr2 = L->next; // 从表头的下一个结点搜索所有符合删除要求的结点while (ptr2 != NULL){if (ptr2->data == m) // ptr2所指结点符合删除要求{ptr1->next = ptr2->next;free(ptr2);}else{ptr1 = ptr2; // ptr1后移一个结点}ptr2 = ptr1->next; // ptr2指向ptr1的后一个结点}return L;}运行结果:

  

  



相关文章