简体   繁体   English

查找字符串中的常见字符

[英]Find common character in a string

Hi i have two different string and i need to find the common character in the string.嗨,我有两个不同的字符串,我需要找到字符串中的公共字符。 I managed to get the common string but i need to return "null string" for input that does not have same character.我设法获得了公共字符串,但我需要为不具有相同字符的输入返回“空字符串”。

Current issues:目前的问题:

input1: abc输入1:abc
input2: def输入 2:定义
output: ' // it shld be "null string";输出:' // 它应该是“空字符串”;

heres my code:继承人我的代码:

#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++;
            }
        }
    }
}

The reason is that strInterset() only calls strcpy() if a match is found, and doesn't modify str3 or the data it points to otherwise.原因是strInterset()仅在找到匹配项时才调用strcpy() ,并且不会修改str3或它指向的其他数据。 The fix is simple - before the loop in strInterset() add the statement修复很简单 - 在strInterset()的循环之前添加语句

 *str3 = '\0';

If a match is found, strcpy() will still be called.如果找到匹配项,仍将调用strcpy() If not, the test being done in main() will succeed.如果没有,则在main()进行的测试将成功。

Initialising the array in main() to zero will also work for the FIRST call of strInterset() .main()的数组初始化为零也适用于strInterset()第一个调用。 It may not work for subsequent calls though (unless main() reinitialises str3 before every call).虽然它可能不适用于后续调用(除非main()在每次调用之前重新初始化str3 )。 Hence it is better to do the initialisation in strInterset() .因此最好在strInterset()进行初始化。

Initialise your str3 explictly to NULL by declaring it like通过声明它来将你的str3显式初始化为 NULL

char str3[50] = { NULL }; 

If you do not do that its an unitialised array with junk/indeterminate values.如果你不这样做,它是一个带有垃圾/不确定值的单元化数组。

You should initialize str3 to NULL , like this:您应该将str3初始化为NULL ,如下所示:

char str3[50] = {0};

since if you don't do that, it will remain an unitialized array, which means that it will invoke Undefined Behavior when accessed, since its values are garbage.因为如果你不这样做,它将保持一个统一的数组,这意味着它会在访问时调用未定义的行为,因为它的值是垃圾。

Moreover, even if common character(s) exist, str3 will not be NULL-terminated.此外,即使存在公共字符, str3也不会以 NULL 结尾。

I would personally change your function to this:我会亲自将您的功能更改为:

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

Output:输出:

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

PS: Compile with warnings enabled and you will get: PS:在启用警告的情况下编译,您将获得:

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

Just change it to: for (; *(str1 + i) != '\\0'; i++) { , or even better for (int i = 0; *(str1 + i) != '\\0'; i++) { .只需将其更改为: for (; *(str1 + i) != '\\0'; i++) { ,甚至更好for (int i = 0; *(str1 + i) != '\\0'; i++) { . This is not your problem, but is good to fix warnings.这不是您的问题,但可以很好地修复警告。

The quick fix should be str3[0] = '\\0' as second line in main .快速修复应该是str3[0] = '\\0'作为main第二行。

But there are more ways you can make your program better:但是还有更多方法可以使您的程序更好:

  • Why you need a full char str3[50] ?为什么你需要一个完整的char str3[50] You could instead use the return value of the function like this: char strInterset(char * str1, char * str2);您可以改为使用函数的返回值,如下所示: char strInterset(char * str1, char * str2); And then add return in the appropriate places.然后在适当的地方添加return (By the way: should that be spellect intersect ?) (顺便说一句:这应该是拼写intersect吗?)

  • Your program uses two nested for -loops (which is slow on large inputs).您的程序使用两个嵌套的for循环(在大输入上速度很慢)。 Instead, you could make an array where each entry corresponds to one character value (look at an ascii-table).相反,您可以创建一个数组,其中每个条目对应一个字符值(查看 ascii 表)。 The array then can contain a true/false whether the character appeared.然后该数组可以包含一个真/假,无论该字符是否出现。 You initialize all entries to 0. Then you run through the first string and for each character you set its entry in the array to 1. Then you run through the second string and for each character you check whether the entry in the array is 1. If such a case is found then you found a character that appears in both strings.您将所有条目初始化为 0。然后您遍历第一个字符串,并为每个字符将其在数组中的条目设置为 1。然后遍历第二个字符串并检查每个字符的数组中的条目是否1。如果发现这种情况,那么您发现了一个出现在两个字符串中的字符。

Here is your function which checks for the common characters and adds them to the result string without the repetition.这是您的函数,它检查公共字符并将它们添加到结果字符串中而不重复。 If you do not care about the repetitions just remove the second if (and only the line where the if is, but leave its body in the brackets )如果您不关心重复,只需删除第二个 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