簡體   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