简体   繁体   English

如何检查输入的字符串中是否存在模式?

[英]How do I check if a pattern exists in an entered string?

I have an assignment where the user enters a string and then a pattern in one function, and then has to check if the pattern exists in the string and how many times it appears and at what offset.我有一个任务,用户在一个函数中输入一个字符串,然后输入一个模式,然后必须检查该模式是否存在于字符串中以及它出现的次数和偏移量。 I'm stumped and my classmates keep giving me cryptic hints.我被难住了,我的同学不断给我神秘的提示。 Below is my get function下面是我的获取功能

int getNums()
{
    printf("Please enter a number: ");      //Initial printf

    int count, patcount;
    int torf;
    char len_num[31];       //The character array for the initial entered string
    char pat_num[6];        //The character array for the entered pattern after initial string
    char *lenptr = len_num;     //pointer to the address of the first element of len_num
    char *patptr = pat_num;     //pointer to the address of the first element of len_num

    scanf("%s", len_num);       //Where the user scans in their wanted number, which is treated as a string
    printf("\n");

    printf("%s\n", lenptr);
    int len = stringLength(lenptr);     //Checks how long string is
    int valid = isValid(len_num);       //Checks if string is valid


    for(count=0; count<len_num[count]; count++)     //Checks if length of string is within appropriate range
    {
        if(len>=10 && len<=30)      //Continues to pattern get if within range
        {
            torf=1;
        }

        else                        //Denies continuation if string is outside of range
        {
            torf=0;
            printf("Not within range! Try again!\n");
            return (1);
        }
    }

    printf("Please enter a pattern: ");     //Initial entry statement for pattern

    scanf("%s", pat_num);                   //User scans in pattern
    printf("\n");

    printf("%s\n", pat_num);
    len = stringPattern(patptr);            //Check how long pattern is
    valid = isValid(pat_num);               //Checks if pattern is valid

    for(patcount=0; patcount<pat_num[patcount]; patcount++) //Checks if length of pattern is within appropriate range
    {
        if(len>=2 && len<=5)                //Continues to pattern check if within range
        {
            torf=1;
        }

        else                                //Denies continuation if pattern is outside of range
        {
            torf=0;
            printf("Pattern not within range! Try again!\n");
            return (1);
        }
    }

    checkPattern();
}

I don't know how I should start my check function.我不知道我应该如何启动我的检查功能。 Not to mention I have to pass by reference with pointers and I'm stuck with that too更不用说我必须通过指针传递引用,而且我也坚持这样做

Since you have asked for the pattern matching function, I did not check your string input function.既然你问的是模式匹配功能,我就没有检查你的字符串输入功能。 You may use this simple driver code to test my solution:您可以使用这个简单的驱动程序代码来测试我的解决方案:

#include <stdio.h>

void findPattern(char* input, char* pattern);

int main()
{
    char input[31], pattern[6];
    printf("Enter the string: ");
    scanf("%s", input);
    printf("Enter the pattern: ");
    scanf("%s", pattern);
    findPattern(input, pattern);
    return 0;
}

I prefer findPattern over checkPattern .我更喜欢findPattern不是checkPattern You shall rename it according to your convenience.您应根据自己的方便对其重命名。 I have not used any library functions apart from that in stdio.h as per your requirement.根据您的要求,除了stdio.h库函数之外,我没有使用任何库函数。 Following is my take on this task, I have explained the logic in the comments.以下是我对这项任务的看法,我已经在评论中解释了逻辑。 Basically, it just iterates over the entire input string once where it checks for a match with the initial character in the pattern.基本上,它只是遍历整个输入字符串一次,它检查与模式中的初始字符是否匹配。 If so, it marks the offset and searches further down the pattern to find a complete match.如果是这样,它会标记偏移量并进一步向下搜索模式以找到完整的匹配项。

void findPattern(char* input, char* pattern)
{
    int i = 0; // iterator for input
    int j = 0; // iterator for pattern

    // solution variables
    int offset = 0;
    int occurrence = 0;

    // Search the entire input string
    while (input[i] != '\0')
    {
        // Mark the offset whenever the first character of the pattern matches
        if (input[i] == pattern[j])
        {
            offset = i;
            // I didn't quite get the relativity of your offset
            // Maybe you need: offset = i + 1;
        }

        // Search for complete pattern match
        while (input[i] != '\0' && pattern[j] == input[i])
        {
            // Go for the next character in the pattern
            ++j;

            // The pattern matched successfully if the entire pattern was searched
            if (pattern[j] == '\0')
            {
                // Display the offset
                printf("\nPattern found at offset %d", offset);

                // Increment the occurrence
                ++occurrence;

                // There are no more characters left in the pattern
                break;
            }
            else
            {
                // Go for the next character in the input
                // only if there are more characters left to be searched in the pattern
                ++i;
            }
        }

        // Reset the pattern iterator to search for a new match
        j = 0;

        // Increment the input iterator to search further down the string
        ++i;
    }

    // Display the occurrence of the pattern in the input string
    printf("\nThe pattern has occurred %d times in the given string", occurrence);
}

I have to pass by reference with pointers and I'm stuck with that too我必须通过指针传递引用,而且我也坚持这样做

If that's the case then instead of findPattern(input, pattern);如果是这种情况,那么代替findPattern(input, pattern); , call this function as: ,调用这个函数为:

findPattern(&input, &pattern);

You may be way over thinking the solution.你可能想太多了。 You have a string input with a number of characters that you want to count the number of multi-character matches of pattern in. One nice thing about strings is you do not need to know how long they are to iterate over them, because by definition a string in C ends with the nul-terminating character.您有一个包含多个字符的字符串input ,您想计算其中pattern的多字符匹配的数量。关于字符串的一个好处是您不需要知道它们需要迭代多长时间,因为根据定义C 中的字符串以空终止字符结尾

This allows you to simply keep an index within your findpattern function and you increment the index each time the character from input matches the character in pattern (otherwise you zero the index).这允许您简单地在findpattern函数中保留一个索引,并且每次input中的字符与pattern中的字符匹配时都会增加索引(否则您将索引归零)。 If you reach the point where pattern[index] == '\\0' you have matched all characters in your pattern.如果您达到pattern[index] == '\\0'的点,则您已匹配模式中的所有字符。

You must always declare a function with a type that will provide a meaningful return to indicate success/failure of whatever operation the function carries out if it is necessary to the remainder of your code (if the function just prints output -- then void is fine).您必须始终声明一个具有类型的函数,该类型将提供有意义的返回,以指示该函数执行的任何操作的成功/失败,如果它对您的代码的其余部分是必要的(如果该函数只是打印输出 - 那么void很好)。

Otherwise, you need to choose a sane return type to indicate whether (and how many) matches of pattern were found in input .否则,您需要选择一个合理的返回类型来指示是否(以及有多少)在input中找到了pattern匹配项。 Here a simple int type will do.这里一个简单的int类型就可以了。 (which limits the number of matches that can be returned to 2147483647 which should be more than adequate). (这将可以返回的匹配数量限制为2147483647 ,这应该2147483647 )。

Putting those pieces together, you could simplify your function to something similar to:将这些部分放在一起,您可以将您的功能简化为类似于:

int findpattern (const char *input, const char *ptrn)
{
    int n = 0, idx = 0;             /* match count and pattern index */

    while (*input) {                /* loop over each char in s */
        if (*input == ptrn[idx])    /* if current matches pattern char */
            idx++;                  /* increment pattern index */
        else    /* otherwize */
            idx = 0;                /* zero pattern index */
        if (!ptrn[idx]) {           /* if end of pattern - match found */
            n++;                    /* increment match count */
            idx = 0;                /* zero index for next match */
        }
        input++;                    /* increment pointer */
    }

    return n;                       /* return match count */
}

Adding a short example program that allows you to enter the pattern and input as the first two arguments to the program (or uses the defaults shown if one or both are not provided):添加一个简短的示例程序,允许您输入patterninput作为程序的前两个参数(如果未提供一个或两个,则使用显示的默认值):

int main (int argc, char **argv) {

    char  *pattern = argc > 1 ? argv[1] : "my",
            *input = argc > 2 ? argv[2] : "my dog has fleas, my cat has none";
    int n;

    if ((n = findpattern (input, pattern)))
        printf ("'%s' occurs %d time(s) in '%s'\n", pattern, n, input);
    else
        puts ("pattern not found");
}

Note how providing a meaningful return allows you to both (1) validate whether or not a match was found;请注意提供有意义的返回如何允许您 (1)验证是否找到匹配项; and (2) provides the number of matches found through the return. (2) 提供通过返回找到的匹配数。 The complete code just needs the header stdio.h , eg完整的代码只需要标题stdio.h ,例如

#include <stdio.h>

int findpattern (const char *input, const char *ptrn)
{
    int n = 0, idx = 0;             /* match count and pattern index */

    while (*input) {                /* loop over each char in s */
        if (*input == ptrn[idx])    /* if current matches pattern char */
            idx++;                  /* increment pattern index */
        else    /* otherwize */
            idx = 0;                /* zero pattern index */
        if (!ptrn[idx]) {           /* if end of pattern - match found */
            n++;                    /* increment match count */
            idx = 0;                /* zero index for next match */
        }
        input++;                    /* increment pointer */
    }

    return n;                       /* return match count */
}

int main (int argc, char **argv) {

    char  *pattern = argc > 1 ? argv[1] : "my",
            *input = argc > 2 ? argv[2] : "my dog has fleas, my cat has none";
    int n;

    if ((n = findpattern (input, pattern)))
        printf ("'%s' occurs %d time(s) in '%s'\n", pattern, n, input);
    else
        puts ("pattern not found");
}

Example Use/Output示例使用/输出

Check for multiple matches:检查多个匹配项:

$ ./bin/findpattern
'my' occurs 2 time(s) in 'my dog has fleas, my cat has none'

A single match:单场比赛:

$ ./bin/findpattern fleas
'fleas' occurs 1 time(s) in 'my dog has fleas, my cat has none'

Pattern not found未找到图案

$ ./bin/findpattern gophers
pattern not found

All the same pattern:所有相同的模式:

$ ./bin/findpattern my "mymymy"
'my' occurs 3 time(s) in 'mymymy'

Output From Function Itself函数本身的输出

While it would be better to provide a return to indicate the number of matches (which would allow the function to be reused in a number of different ways), if you did just want to make this an output function that outputs the results each time it is called, then simply move the output into the function and declare another pointer to input so input is preserved for printing at the end.虽然最好提供一个返回值来指示匹配的数量(这将允许以多种不同方式重用该函数),但如果您只是想让它成为每次输出结果的输出函数被调用,然后简单地输出移动到功能和声明另一个指针input ,以便input被保存在最后打印。

The changes are minimal, eg变化很小,例如

#include <stdio.h>

void findpattern (const char *input, const char *ptrn)
{
    const char *p = input;          /* pointer to input */
    int n = 0, idx = 0;             /* match count and pattern index */

    while (*p) {                    /* loop over each char in s */
        if (*p == ptrn[idx])        /* if current matches pattern char */
            idx++;                  /* increment pattern index */
        else    /* otherwize */
            idx = 0;                /* zero pattern index */
        if (!ptrn[idx]) {           /* if end of pattern - match found */
            n++;                    /* increment match count */
            idx = 0;                /* zero index for next match */
        }
        p++;                        /* increment pointer */
    }

    if (n)  /* output results */
        printf ("'%s' occurs %d time(s) in '%s'\n", ptrn, n, input);
    else
        puts ("pattern not found");
}

int main (int argc, char **argv) {

    char  *pattern = argc > 1 ? argv[1] : "my",
            *input = argc > 2 ? argv[2] : "my dog has fleas, my cat has none";

    findpattern (input, pattern);
}

(use and output are the same as above) (使用和输出同上)

Look things over and let me know if you have further questions.仔细检查一下,如果您还有其他问题,请告诉我。

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

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