PTA - C编程 NoD - 数组-指针-字符串 (10道题)

6-1使用函数实现字符串部分复制
6-2删除字符
6-3字符串的连接
6-4函数实现字符串逆序
6-5指定位置输出字符串
6-6查找子串
7-1找最小的字符串
7-2字符串排序
7-3找最长的字符串
7-4A-B

6-1 使用函数实现字符串部分复制

本题要求编写函数,将输入字符串 t 中从第 m 个字符开始的全部字符复制到字符串 s 中。

void strmcpy(char *t, int m, char *s) {
    // 因为s本来就是空的,所以直接返回,s就是空字符串
    if (!t) return;  // t 如果是空的,直接返回
    while (m > 1) {    // 从 1 开始
        if (*t == '\0') return; // m 大于 t 的长度了,直接返回
        --m;
        ++t;
    }
    while (*t != '\0')  *(s++) = *(t++);
    *s = '\0';
}

6-2 删除字符

本题要求实现一个删除字符串中的指定字符的简单函数。

    常规做法有两种:

  1.  从前往后遍历字符串,如果是要删除的就把后边所有的前移一位
  2.  从前往后遍历字符串,把要保留的部分放到一个新的字符串数组中,再赋值会给 str

    第一个方法不需要额外的空间,但是如果要删除的字符出现的次数很多的话,会非常非常慢,所以我用的第二种,同时还要考虑极端情况(没有要删除的、全是要删除的、str字符串长度超过 MAXN)。

void delchar(char *str, char c) {
    if (!str) return;
    char tmp[201];  // 21不够长
    char *tHead = tmp, *tStr = str;
    int foundc = 0;
    while (*tStr != '\0') {
        if (*tStr == c) {
            ++tStr;
            foundc = 1;
        }
        else
            *(tHead++) = *(tStr++);
    }
    if(foundc == 0) return ;  // 没有要删除的就直接返回
    if(tHead == tmp) // 字符串中全都是字符 c,也就是删除之后都没了
    {
        *str = '\0';
        return;
    }
    tStr = str;
    tHead = tmp;
    while (*tHead != '\0')
        *tStr++ = *tHead++;
    *tStr = '\0';
}

 6-3 字符串的连接

本题要求实现一个函数,将两个字符串连接起来。

char* str_cat(char* s, char* t) {
    char* tmps = s;
    while(*tmps != '\0') ++tmps;
    while(*t != '\0')    *tmps++ = *t++;
    *tmps = '\0';
    return s; // 最后要返回 s 的首地址
}

6-4 函数实现字符串逆序

    既然不让定义数组,那肯定就是要在 p 这个字符串数组自身中交换元素,达到逆序效果,所以需要先得到字符串长度,然后对着交换对应元素就行。

void f(char *p) {
    char* tmp = p;
    int len = 0;
    while(*tmp != '\0') { // 得到的 len 是不包括 '\0' 的长度
        ++tmp;
        ++len;
    }
    for(int i = 0; i < len / 2; i++) {  // 不需要 <=
        char t = p[i];
        p[i] = p[len - 1 - i];
        p[len - 1 - i] = t;
    }
    p[len] = '\0';
}

6-5 指定位置输出字符串

char* match(char* s, char ch1, char ch2) {
    char *tmps1 = s;
    while (*tmps1 != ch1) {
        if (*tmps1 == '\0')  { // 没有找到ch1,直接返回
            printf("\n");
            char* ret = "\0";
            return ret;   // 必须这样才能过第二个测试点
        }
        ++tmps1;
    }
    // 循环结束 tmps1 就是 ch1 的位置
    char *tmps1res = tmps1;
    while (*tmps1 != '\0') {
        printf("%c", *tmps1++);
        if (*tmps1 == ch2) {
            printf("%c\n", ch2);
            return tmps1res;
        }
    }
    printf("\n");
    return tmps1res;
}

6-6 查找子串

char* search(char *s, char *t) {
    char* tmps = s;
    while(1) {
        if(*tmps == '\0') return NULL;
        if(*tmps == *t) {
            char *res = tmps, *tmpt = t;
            while(1) {
                ++tmps;
                ++tmpt;
                if(*tmpt == '\0') return res;    // 把t匹配完了都是对的,那就是找到了
                if(*tmps == '\0' || *tmpt == '\0' || *tmps != *tmpt) break;
            }
        }
        ++tmps;
    }
}

7-1 找最小的字符串

 

#include <stdio.h>
int main() {
    int n;
    scanf("%d", &n);
    char ch[n][81];
    for(int i = 0; i < n; i++)  scanf("%s", ch[i]);
    int min_idx = 0;
    for(int i = 1; i < n; i++)
        for(int j = 0; j < 81; j++) {
            if(ch[i][j] > ch[min_idx][j])
                break;
            if(ch[i][j] < ch[min_idx][j] || (ch[i][j] == '\0' && ch[min_idx][j] != '\0')) {
                min_idx = i;
                break;
            }
        }
    printf("Min is: %s\n", ch[min_idx]);
    return 0;
}

7-2 字符串排序

    下面这个是没有用 strlen、strcmp、strcpy 的方法。 

#include <stdio.h>
int main() {
    char ch[5][81];
    char c;
    // 读取五个字符串 (scanf("%s") 遇空格停止)
	for(int i = 0; i < 5; i++)
	  scanf("%s", ch[i]);
    int flag[5] = { 1, 1, 1, 1, 1 };	// 1表示没有输出过,0表示输出过了
    printf("After sorted:\n");
    for(int i = 0; i < 5; i++)	// 共输出5次,每次选最小的,并让对应flag为0
    {
        int min_idx = -1;
        for(int j = 0; j < 5; j++) {
            if (flag[j] == 0) continue;
            if (min_idx == -1) {
                min_idx = j;
                continue;
            }
            for (int t = 0; t < 81; t++) {
                if (ch[min_idx][t] == '\0')
                    break;
                if(ch[j][t] == '\0' || ch[j][t] < ch[min_idx][t]) {
                    min_idx = j;
                    break;
                }
                if (ch[j][t] > ch[min_idx][t])
                    break;
            }
        }
        printf("%s\n", ch[min_idx]); // 输出最小的字符串
        flag[min_idx] = 0;
    }
    return 0;
}

    用string.h中的函数就会简单一些。

#include <stdio.h>
#include <string.h>
int main() {
    char ch[5][81];
    char c;
    // 读取五个字符串
    for(int i = 0; i < 5; i++)
      scanf("%s", ch[i]);
    int flag[5] = { 1, 1, 1, 1, 1 };	// 1表示没有输出过,0表示输出过了
    printf("After sorted:\n");
    for(int i = 0; i < 5; i++)	// 共输出5次,每次选最小的,并让对应flag为0
    {
        int min_idx = -1;
        for(int j = 0; j < 5; j++) {
            if (flag[j] == 0) continue;
            if (min_idx == -1) {
                min_idx = j;
                continue;
            }
            // 比较两个字符串大小
            if(strcmp(ch[j], ch[min_idx]) < 0)
                min_idx = j;
        }
        printf("%s\n", ch[min_idx]); // 输出最小的字符串
        flag[min_idx] = 0;
    }
    return 0;
}

7-3 找最长的字符串

#include <stdio.h>
#include <string.h>
int main() {
    int n, max_len = 0, max_idx = -1;
    scanf("%d", &n);
    char ch[n][81];
    for(int i = 0; i < n; i++) {
        scanf("%s", ch[i]);
        if(strlen(ch[i]) > max_len) {
            max_len = strlen(ch[i]);
            max_idx = i;
        }
    }
    printf("The longest is: %s\n", ch[max_idx]);
    return 0;
}

7-4 A-B

#include <stdio.h>
#include <string.h>
int main() {
    int i= 0;
    char a[10001], b[10001], ch;
    gets(a);
    gets(b);
    for(i = 0; a[i] != '\0'; i++) {
        int isfound = 0;
        for(int j = 0; b[j] != '\0'; j++)
            if(a[i] == b[j]) {
                isfound = 1;
                break;
            }
        if(isfound == 0)
            printf("%c", a[i]);
    }
    return 0;
}

 

  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值