交换字符串中两个最频繁出现的字母 [英] Swap occurrences of two most frequent letters in a string

查看:102
本文介绍了交换字符串中两个最频繁出现的字母的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道代码中的问题是什么,但是当我编译时会得到:

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

这是代码:

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

#define STR_LEN 50

int main(void) {
    int i = 0, j = 0, length = 0, count1 = 0, count2 = 0, count3 = 0;
    char letter3 = 'a', letter2 = 'a', string[STR_LEN] = { 0 };

    length = strlen(string);
    printf("Enter a sentence: ");
    fgets(string, STR_LEN, stdin);

    for (i = 0; i < length; i++) {
        for (j = 0; j < length; j++) {
            if (string[i] == string[j]) {
                count1++;
            } else {
                count1 = 0;
            }
        }
        if (count1 > count3) {
            count2 = count3;
            count3 = count1;
            letter2 = letter3;
            letter3 = string[i];
        } else
        if (count1 > count2) {
            count2 = count1;
            letter2 = string[i];
        }
    }

    string[strcspn(string, letter2)] = letter3;
    string[strcspn(string, letter3)] = letter2;

    printf("\n %s", string);

    system("pause");

    return 0;
}

该代码应该从用户那里获得一个句子并切换最常用的字母

The code supposed to get a sentence from the user and switch the most common letter in the sentence with the 2nd common letter.

推荐答案

眼前的问题



strcspn()函数将两个字符串作为参数,但是您要传递一个字符串和一个字符。您需要以某种方式将字符转换为字符串。一种方法是:

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;

但是,第一次通话会更改 letter2 letter3 ;第二个调用将 letter3 (可能是上一个调用中刚替换的第一次出现)更改为 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.

一种可能是这样:

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

使用宏 NULL_VALUE的唯一原因使得三行 map()的对称性不言而喻。

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

我调用了程序 ccswap19 ,并且我使用了Bash这里字符串来提供数据- putchar('\n'); 表示输出出现在与提示符不同的一行上。如果您以交互方式运行程序,则在原始打印之前会有空白行。

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]
$

这篇关于交换字符串中两个最频繁出现的字母的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆