简体   繁体   中英

C: How to find that a certain number of characters are present in a string in any sequence?

So the given task is to make a function that checks for any string if

  1. All 5 letters 'a', 'b', 'c', 'd', and 'e' are included (in any sequence) and
  2. The string 'abcde' is a substring of the given string. If 1 holds (but 2 does not), return 1. If both 1 and 2 holds, return 2. Otherwise, return 0.

Examples:

checkabcde(“someaxbxcxdxemm”) -> 1
checkabcde(“someOtherValue”) -> 0
checkabcde(“xyabcdeping”) -> 2
checkabcde(“someaxuxdxlxammabcde”) -> 2

In my approach I've been able to find that is the substring is "abcde" but unable to determine that the string contains 'a', 'b', 'c', 'd', 'e' in any sequence

int checkabcde(char str[]) {

  char str2[] = {
    'a',
    'b',
    'c',
    'd',
    'e'
  };

  char str3[5]; //to be filled with elements from str2 when found inconsecutive order

  int i, z, x, f;

  z = 0; //position for str3
  f = 0; //flag for similarity comparison of str2 and str3

  for (i = 0; i < strlen(str); i++) {
    for (x = 0; x < strlen(str2); x++) {
      if (str[i] == str2[x]) {

        if ((str[i] == 'a') && (str[i + 1] == 'b') && (str[i + 2] == 'c') && (str[i + 3] == 'd') && (str[i + 4] == 'e')) {
          return 2;
        } else {

          if (str3[z] != str[z - 1]) {
            str3[z] = str2[x];
            z++;
          }

        }

      }
    }
  }

  for (i = 0; i < 5; i++) {
    for (x = 0; x < 5; x++) {
      if (str2[i] == str3[x]) {
        f++;
      }
    }
  }

  if (f == 5) {
    return 1;
  } else if (f1 == 0) {
    return 0;
  }
}

edit: pointers not allowed

  1. For 1, you could use f[256] set f[ch] = 1 for all char in s1 then check whether f[ch] == 1 for each char in s2
  2. For 2, you could use strstr() see http://man7.org/linux/man-pages/man3/strstr.3.html

The following code could work:

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

int check(const char* s1, const char* s2) {
  int f[256];
  memset(f, 0, sizeof(f));

  // check 1
  for (int i = 0; s1[i] != '\0'; ++i)
    f[s1[i]] = 1;
  for (int i = 0; s2[i] != '\0'; ++i)
    if (f[s2[i]] == 0)
      return 0;
  // check 2
  return strstr(s1, s2) == NULL ? 1 : 2;
}

int main(void) {
  printf("%d\n", check("someaxbxcxdxemm",      "abcde"));
  printf("%d\n", check("someOtherValue",       "abcde"));
  printf("%d\n", check("xyabcdeping",          "abcde"));
  printf("%d\n", check("someaxuxdxlxammabcde", "abcde"));
  return 0;
}

You can use a separate structure to check for the individual characters in addition to looking for the substring.

An array of five bools could be used to store the present of each character. eg:

bool chars[5] = {false};

for (int i = 0; i < strlen(str); i++) {
    char c = str[i];
    switch(c) {
        case 'a':
            chars[0] = true;
            break;
        case 'b':
            chars[1] = true;
            break;
        // include cases for each character you are looking for
    }
}

If at the end each entry in the chars array is true you know the string contains all characters.

You can do this in addition to what you are already doing to match the substring.

You may also want to look at some other methods of checking if a string contains a certain substring.

Try something like this:

int checkabcde(char str[]) {

    // Check if string contains substring "abcde"
    if (strstr(str, "abcde") != NULL) {
        return 2;
    }

    int charCounts[5] = {0, 0, 0, 0, 0};
    int length = strlen(str);
    int i = 0;

    // Keep counts of each occurrence of a,b,c,d,e
    for(; i < length; i++) {
        // If "abcde" contains the current character
        if (strchr("abcde", str[i]) != NULL) {
            charCounts[str[i] - 'a']++;
        }
    }

    i = 0;

    // Check if any of the counts for a,b,c,d,e are 0
    for (; i < 5; i++) {
        if (charCounts[i] == 0) {
            return 0;
        }
    }

    // Otherwise we must have found at least 1 of each a,b,c,d,e
    return 1;
}

At each index in str the sub loop looks for the substring match. If it is found, 2 is returned. The found loop looks to see if that character, str[index], is one of abcde . If it is, the matching index in the check array is set to space.
After all charecters in str have been processed, compare abcde to check . If there is a match, that matching character is missing in str . Return 0.

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

int checkabcde ( char str[]) {
    char abcde[] = "abcde";
    char check[] = "abcde";
    int index = 0;
    int match = 1;
    int length = strlen ( str);
    int span = strlen ( abcde);

    while ( str[index]) {
        if ( str[index] == abcde[0]) {
            match = 1;
            for ( int sub = 0; sub < span; ++sub) {
                if ( index + sub > length || str[index + sub] != abcde[sub]) {
                    match = 0;
                    break;
                }
            }
            if ( match) {
                return 2;
            }
        }
        for ( int found = 0; index + found < length && found < span; ++found) {
            if ( str[index + found] == abcde[found]) {
                check[found] = ' ';
            }
        }
        index++;
    }
    for ( int found = 0; found < span; ++found) {
        if ( check[found] == abcde[found]) {
            return 0;
        }
    }
    return 1;
}

int main( void) {
    char lines[][30] = {
        "someaxbxcxdxemm"
        , "someOtherValue"
        , "xyabcdeping"
        , "someaxuxdxlxammabcde"
        , "vu4ndljeibn2c9n@aiendjba"
        , "dbcaeddeaabcceabcde"
    };

    for ( int each = 0; each < 6; ++each) {
        printf ( "for [%s] result = %d\n", lines[each], checkabcde ( lines[each]));
    }
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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