Swap occurrences of two most frequent letters in a string

后端 未结 2 1181
情深已故
情深已故 2021-01-26 12:00

I don\'t know what is the problem in my code, but when I compile I get:

warning: passing arg 2 of `strcspn\' makes pointer from integer without a cast

相关标签:
2条回答
  • 2021-01-26 12:15

    strcspn(const char *str1, const char *str2) looks for the first instance of any characters in the second string in the first string. You are passing a character instead of a string as the second argument. You want the function strchr(const char *string, int character), which looks for a single character.

    0 讨论(0)
  • 2021-01-26 12:31

    The immediate problem

    The strcspn() function takes two strings as arguments, but you're passing a string and a character. You need to convert the character into a string somehow. One way to do that would be:

    int sep[2] = "";
    sep[0] = letter2;
    string[strcspn(string, sep)] = letter3;
    sep[0] = letter3;
    string[strcspn(string, sep)] = letter2;
    

    However, the first call changes the first occurrence of letter2 to letter3; the second call changes the first occurrence of letter3 (which might be the one just replaced in the previous call) with letter2. This is not a complete job of transforming the strings — you need to scan the whole string making the changes.

    Implementing a solution

    One possibility is this:

    #include <ctype.h>
    #include <stdio.h>
    #include <string.h>
    
    #define NULL_VALUE '\0'
    
    static inline void map(char *str, int len, int c_old, int c_new)
    {
        for (int i = 0; i < len; i++)
        {
            if (str[i] == c_old)
                str[i] = c_new;
        }
    }
    
    int main(void)
    {
        char buffer[4096];
    
        printf("Enter a sentence: ");
        if (fgets(buffer, sizeof(buffer), stdin) == 0)
            return 0;
        int length = strlen(buffer);
        if (length > 0)
            buffer[--length] = '\0';
    
        putchar('\n');
        printf("Original [%s]\n", buffer);
    
        int count[256] = { 0 };
        for (int i = 0; i < length; i++)
        {
            if (isalpha((unsigned char)buffer[i]))
                count[(unsigned char)buffer[i]]++;
        }
    
        int max1_count = 0;
        int max2_count = 0;
        char max1_value = '\0';
        char max2_value = '\0';
        for (int i = 0; i < 256; i++)
        {
            if (count[i] > max1_count)
            {
                max2_count = max1_count;
                max2_value = max1_value;
                max1_count = count[i];
                max1_value = i;
            }
            else if (count[i] > max2_count)
            {
                max2_count = count[i];
                max2_value = i;
            }
        }
    
        /*
        ** Since a string is a sequence of non-null character codes followed
        ** by a null byte, it is safe to use '\0' as the temporary value in
        ** the three-step swap operation
        */
        if (max2_count > 0)
        {
            map(buffer, length, max1_value, NULL_VALUE);
            map(buffer, length, max2_value, max1_value);
            map(buffer, length, NULL_VALUE, max2_value);
        }
    
        printf("Revised  [%s]\n", buffer);
    
        return 0;
    }
    

    The only reason for using the macro NULL_VALUE is so that the symmetry of the three map() lines is self-evident.

    Example runs

    I called the program ccswap19, and I used Bash 'here strings' to supply the data — the putchar('\n'); means that the output appears on a separate line from the prompt. There'd be a blank line before the 'Original' printing if you ran the program interactively.

    $ ccswap19 <<< "The hidden costs of the exodus are now revealed for all to see."
    Enter a sentence: 
    Original [The hidden costs of the exodus are now revealed for all to see.]
    Revised  [Tho hiddon cests ef tho oxedus aro new rovoalod fer all te soo.]
    $ ccswap19 <<< "aaaaaaaaaaaa"
    Enter a sentence: 
    Original [aaaaaaaaaaaa]
    Revised  [aaaaaaaaaaaa]
    $ ccswap19 <<< "aaaabaaaaaaa"
    Enter a sentence: 
    Original [aaaabaaaaaaa]
    Revised  [bbbbabbbbbbb]
    $
    
    0 讨论(0)
提交回复
热议问题