繁体   English   中英

查找字符串中的常见字符

[英]Find common character in a string

嗨,我有两个不同的字符串,我需要找到字符串中的公共字符。 我设法获得了公共字符串,但我需要为不具有相同字符的输入返回“空字符串”。

目前的问题:

输入1:abc
输入 2:定义
输出:' // 它应该是“空字符串”;

继承人我的代码:

#include <stdio.h>
#include <string.h>

void strInterset(char * str1, char * str2, char * str3);

int main() {
    char str1[50], str2[50], str3[50];

    printf("Enter str1: \n");
    scanf("%s", str1);
    printf("Enter str2: \n");
    scanf("%s", str2);
    strInterset(str1, str2, str3);

    if (*str3 == '\0')
        printf("strIntersect(): null string\n");
    else
        printf("strIntersect(): %s\n", str3);

    return 0;
}

void strInterset(char * str1, char * str2, char * str3) {
    int i = 0, j;
    for (i; *(str1 + i) != '\0'; i++) {
        for (j = 0; *(str2 + j) != '\0'; j++) {
            if ( *(str2 + j) == *(str1 + i)) {
                strcpy(str3, str1 + i);
                str3++;
            }
        }
    }
}

原因是strInterset()仅在找到匹配项时才调用strcpy() ,并且不会修改str3或它指向的其他数据。 修复很简单 - 在strInterset()的循环之前添加语句

 *str3 = '\0';

如果找到匹配项,仍将调用strcpy() 如果没有,则在main()进行的测试将成功。

main()的数组初始化为零也适用于strInterset()第一个调用。 虽然它可能不适用于后续调用(除非main()在每次调用之前重新初始化str3 )。 因此最好在strInterset()进行初始化。

通过声明它来将你的str3显式初始化为 NULL

char str3[50] = { NULL }; 

如果你不这样做,它是一个带有垃圾/不确定值的单元化数组。

您应该将str3初始化为NULL ,如下所示:

char str3[50] = {0};

因为如果你不这样做,它将保持一个统一的数组,这意味着它会在访问时调用未定义的行为,因为它的值是垃圾。

此外,即使存在公共字符, str3也不会以 NULL 结尾。

我会亲自将您的功能更改为:

void strInterset(char * str1, char * str2, char * str3) {
    int i = 0, j;
    *str3 = '\0'; // NULL terminate
    for (i; *(str1 + i) != '\0'; i++) {
        ...
}

输出:

Enter str1: abc
Enter str2: dfg
strIntersect(): null string

PS:在启用警告的情况下编译,您将获得:

prog.c: In function 'strInterset':
prog.c:26:5: warning: statement with no effect [-Wunused-value]
     for (i; *(str1 + i) != '\0'; i++) {
     ^~~

只需将其更改为: for (; *(str1 + i) != '\\0'; i++) { ,甚至更好for (int i = 0; *(str1 + i) != '\\0'; i++) { . 这不是您的问题,但可以很好地修复警告。

快速修复应该是str3[0] = '\\0'作为main第二行。

但是还有更多方法可以使您的程序更好:

  • 为什么你需要一个完整的char str3[50] 您可以改为使用函数的返回值,如下所示: char strInterset(char * str1, char * str2); 然后在适当的地方添加return (顺便说一句:这应该是拼写intersect吗?)

  • 您的程序使用两个嵌套的for循环(在大输入上速度很慢)。 相反,您可以创建一个数组,其中每个条目对应一个字符值(查看 ascii 表)。 然后该数组可以包含一个真/假,无论该字符是否出现。 您将所有条目初始化为 0。然后您遍历第一个字符串,并为每个字符将其在数组中的条目设置为 1。然后遍历第二个字符串并检查每个字符的数组中的条目是否1。如果发现这种情况,那么您发现了一个出现在两个字符串中的字符。

这是您的函数,它检查公共字符并将它们添加到结果字符串中而不重复。 如果您不关心重复,只需删除第二个 if(并且仅删除 if 所在的行,但将其主体保留在括号中)

char *strcomm(const char *s1, const char *s2, char *s3)
{
    const char *tmp;
    char *tmps3 = s3;
    *s3 = 0;
    while(*s1)
    {
        tmp = s2;
        while(*tmp)
        {
            if(*s1 == *tmp)
                if(strchr(s3,*s1) == NULL)
                {
                    *s3++ = *s1;
                    *s3 = 0;
                }
            tmp++;
        }
        s1++;
    }
    return tmps3;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM