交换字符串中出现频率最高的两个字母
Swap occurrences of two most frequent letters in a string
我不知道我的代码有什么问题,但是当我编译时我得到:
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;
}
代码应该从用户那里得到一个句子,并将句子中最常见的字母与第二个常见的字母切换。
strcspn(const char *str1, const char *str2) 在第一个字符串中查找第二个字符串中任何字符的第一个实例。您正在传递一个字符而不是字符串作为第二个参数。您需要查找单个字符的函数 strchr(const char *string, int character)。
眼前的问题
strcspn()
函数接受两个字符串作为参数,但您传递的是一个字符串和一个字符。您需要以某种方式将字符转换为字符串。一种方法是:
int sep[2] = "";
sep[0] = letter2;
string[strcspn(string, sep)] = letter3;
sep[0] = letter3;
string[strcspn(string, sep)] = letter2;
但是,第一次调用将 letter2
的第一次出现更改为 letter3
;第二次调用将第一次出现的 letter3
(可能是上次调用中刚刚替换的那个)更改为 letter2
。这不是 t运行 形成字符串的完整工作 — 您需要扫描整个字符串进行更改。
实施解决方案
一种可能是这样的:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#define NULL_VALUE '[=11=]'
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] = '[=11=]';
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 = '[=11=]';
char max2_value = '[=11=]';
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 '[=11=]' 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()
线的对称性是 self-evident.
示例运行
我调用了程序 ccswap19
,我使用 Bash 'here strings' 来提供数据 — putchar('\n');
意味着输出与迅速的。如果您 运行 程序是交互式的,那么在 'Original' 打印之前会有一个空行。
$ 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]
$
我不知道我的代码有什么问题,但是当我编译时我得到:
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;
}
代码应该从用户那里得到一个句子,并将句子中最常见的字母与第二个常见的字母切换。
strcspn(const char *str1, const char *str2) 在第一个字符串中查找第二个字符串中任何字符的第一个实例。您正在传递一个字符而不是字符串作为第二个参数。您需要查找单个字符的函数 strchr(const char *string, int character)。
眼前的问题
strcspn()
函数接受两个字符串作为参数,但您传递的是一个字符串和一个字符。您需要以某种方式将字符转换为字符串。一种方法是:
int sep[2] = "";
sep[0] = letter2;
string[strcspn(string, sep)] = letter3;
sep[0] = letter3;
string[strcspn(string, sep)] = letter2;
但是,第一次调用将 letter2
的第一次出现更改为 letter3
;第二次调用将第一次出现的 letter3
(可能是上次调用中刚刚替换的那个)更改为 letter2
。这不是 t运行 形成字符串的完整工作 — 您需要扫描整个字符串进行更改。
实施解决方案
一种可能是这样的:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#define NULL_VALUE '[=11=]'
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] = '[=11=]';
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 = '[=11=]';
char max2_value = '[=11=]';
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 '[=11=]' 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()
线的对称性是 self-evident.
示例运行
我调用了程序 ccswap19
,我使用 Bash 'here strings' 来提供数据 — putchar('\n');
意味着输出与迅速的。如果您 运行 程序是交互式的,那么在 'Original' 打印之前会有一个空行。
$ 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]
$