C语言 计算字符串中每个字母出现的次数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13213422/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Count the number of occurrences of each letter in string
提问by xlharambe
How can I count the number of occurrences in c of each letter (ignoring case) in the string? So that it would print out letter: # number of occurences, I have code to count the occurences of one letter, but how can I count the occurence of each letter in the string?
如何计算字符串中每个字母(忽略大小写)在 c 中出现的次数?为了打印出来letter: # number of occurences,我有代码来计算一个字母的出现次数,但是如何计算字符串中每个字母的出现次数?
{
char
int count = 0;
int i;
//int length = strlen(string);
for (i = 0; i < 20; i++)
{
if (string[i] == ch)
{
count++;
}
}
return count;
}
output:
输出:
a : 1
b : 0
c : 2
etc...
回答by
Let's assume you have a system where charis eight bit and all the characters you're trying to count are encoded using a non-negative number. In this case, you can write:
假设您有一个char八位系统,并且您尝试计算的所有字符都使用非负数进行编码。在这种情况下,您可以编写:
const char *str = "The quick brown fox jumped over the lazy dog.";
int counts[256] = { 0 };
int i;
size_t len = strlen(str);
for (i = 0; i < len; i++) {
counts[(int)(str[i])]++;
}
for (i = 0; i < 256; i++) {
if ( count[i] != 0) {
printf("The %c. character has %d occurrences.\n", i, counts[i]);
}
}
Note that this will count all the characters in the string. If you are 100% absolutely positively sure that your string will have only letters (no numbers, no whitespace, no punctuation) inside, then 1. asking for "case insensitiveness" starts to make sense, 2. you can reduce the number of entries to the number of characters in the English alphabet (namely 26) and you can write something like this:
请注意,这将计算字符串中的所有字符。如果你 100% 绝对肯定你的字符串里面只有字母(没有数字,没有空格,没有标点符号),那么 1. 要求“不区分大小写”开始有意义,2. 你可以减少条目的数量到英文字母表中的字符数(即 26),你可以这样写:
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
const char *str = "TheQuickBrownFoxJumpedOverTheLazyDog";
int counts[26] = { 0 };
int i;
size_t len = strlen(str);
for (i = 0; i < len; i++) {
// Just in order that we don't shout ourselves in the foot
char c = str[i];
if (!isalpha(c)) continue;
counts[(int)(tolower(c) - 'a')]++;
}
for (i = 0; i < 26; i++) {
printf("'%c' has %2d occurrences.\n", i + 'a', counts[i]);
}
回答by dasblinkenlight
Like this:
像这样:
int counts[26];
memset(counts, 0, sizeof(counts));
char *p = string;
while (*p) {
counts[tolower(*p++) - 'a']++;
}
This code assumes that the string is null-terminated, and that it contains only characters athrough zor Athrough Z, inclusive.
此代码假定字符串以 null 结尾,并且它只包含字符athroughz或Athrough Z,包括两者。
To understand how this works, recall that after conversion tolowereach letter has a code between aand z, and that the codes are consecutive. As the result, tolower(*p) - 'a'evaluates to a number from 0to 25, inclusive, representing the letter's sequential number in the alphabet.
要了解这是如何工作的,请记住转换后tolower每个字母都有一个介于a和之间的代码z,并且这些代码是连续的。结果,tolower(*p) - 'a'计算结果为从0to开始的数字25,包括这两个数字,表示字母在字母表中的顺序号。
This code combines ++and *pto shorten the program.
这段代码结合++并*p缩短了程序。
回答by chux - Reinstate Monica
After Accept Answer
接受答案后
A method that meets these specs: (IMO, the other answers do not meet all)
符合这些规范的方法:(IMO,其他答案不符合所有要求)
It is practical/efficient when
charhas a widerange. Example:CHAR_BITis16or32, so no use ofbool Used[1 << CHAR_BIT];Works for verylong strings (use
size_trather thanint).Does not rely on ASCII. (
Use Upper[])Defined behavior when a
char< 0.is...()functions are defined forEOFandunsigned charstatic const char Upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; static const char Lower[] = "abcdefghijklmnopqrstuvwxyz"; void LetterOccurrences(size_t *Count, const char *s) { memset(Count, 0, sizeof *Count * 26); while (*s) { unsigned char ch = *s; if (isalpha(ch)) { const char *caseset = Upper; char *p = strchr(caseset, ch); if (p == NULL) { caseset = Lower; p = strchr(caseset, ch); } if (p != NULL) { Count[p - caseset]++; } } } } // sample usage char *s = foo(); size_t Count[26]; LetterOccurrences(Count, s); for (int i=0; i<26; i++) printf("%c : %zu\n", Upper[i], Count[i]); }
当范围
char很广时,它是实用/高效的。示例:CHAR_BITis16or32,所以不使用bool Used[1 << CHAR_BIT];适用于很长的字符串(使用
size_t而不是int)。不依赖于 ASCII。(
Use Upper[])当 a
char< 0.is...()为EOF和定义函数时的定义行为unsigned charstatic const char Upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; static const char Lower[] = "abcdefghijklmnopqrstuvwxyz"; void LetterOccurrences(size_t *Count, const char *s) { memset(Count, 0, sizeof *Count * 26); while (*s) { unsigned char ch = *s; if (isalpha(ch)) { const char *caseset = Upper; char *p = strchr(caseset, ch); if (p == NULL) { caseset = Lower; p = strchr(caseset, ch); } if (p != NULL) { Count[p - caseset]++; } } } } // sample usage char *s = foo(); size_t Count[26]; LetterOccurrences(Count, s); for (int i=0; i<26; i++) printf("%c : %zu\n", Upper[i], Count[i]); }
回答by Mike
One simple possibility would be to make an array of 26 ints, each is a count for a letter a-z:
一种简单的可能性是创建一个包含 26 个整数的数组,每个整数都是一个字母 az 的计数:
int alphacount[26] = {0}; //[0] = 'a', [1] = 'b', etc
Then loop through the string and increment the count for each letter:
然后遍历字符串并增加每个字母的计数:
for(int i = 0; i<strlen(mystring); i++) //for the whole length of the string
if(isalpha(mystring[i]))
alphacount[tolower(mystring[i])-'a']++; //make the letter lower case (if it's not)
//then use it as an offset into the array
//and increment
It's a simple idea that works for A-Z, a-z. If you want to separate by capitals you just need to make the count 52 instead and subtract the correct ASCII offset
这是一个简单的想法,适用于 AZ,az。如果你想用大写分隔,你只需要将计数改为 52 并减去正确的 ASCII 偏移量
回答by mrc_03
#include <stdio.h>
#include <string.h>
void main()
{
printf("PLEASE ENTER A STRING\n");
printf("GIVE ONLY ONE SPACE BETWEEN WORDS\n");
printf("PRESS ENETR WHEN FINISHED\n");
char str[100];
int arr[26]={0};
char ch;
int i;
gets(str);
int n=strlen(str);
for(i=0;i<n;i++)
{
ch=tolower(str[i]);
if(ch>=97 && ch<=122)
{
arr[ch-97]++;
}
}
for(i=97;i<=122;i++)
printf("%c OCCURS %d NUMBER OF TIMES\n",i,arr[i-97]);
return 0;
}
回答by Megharaj
#include<stdio.h>
#include<string.h>
#define filename "somefile.txt"
int main()
{
FILE *fp;
int count[26] = {0}, i, c;
char ch;
char alpha[27] = "abcdefghijklmnopqrstuwxyz";
fp = fopen(filename,"r");
if(fp == NULL)
printf("file not found\n");
while( (ch = fgetc(fp)) != EOF) {
c = 0;
while(alpha[c] != 'for (int i=0;i<word.length();i++){
int counter=0;
for (int j=0;j<word.length();j++){
if(word.charAt(i)==word.charAt(j))
counter++;
}// inner for
JOptionPane.showMessageDialog( null,word.charAt(i)+" found "+ counter +" times");
}// outer for
') {
if(alpha[c] == ch) {
count[c]++;
}
c++;
}
}
for(i = 0; i<26;i++) {
printf("character %c occured %d number of times\n",alpha[i], count[i]);
}
return 0;
}
回答by mero
#include<stdio.h>
void frequency_counter(char* str)
{
int count[256] = {0}; //partial initialization
int i;
for(i=0;str[i];i++)
count[str[i]]++;
for(i=0;str[i];i++) {
if(count[str[i]]) {
printf("%c %d \n",str[i],count[str[i]]);
count[str[i]]=0;
}
}
}
void main()
{
char str[] = "The quick brown fox jumped over the lazy dog.";
frequency_counter(str);
}
回答by kamalnayan242
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Node {
char data;
int counter;
struct Node* next;
};
void printLinkList(struct Node* head)
{
while (head != NULL) {
printf("\n%c occur %d", head->data, head->counter);
head = head->next;
}
}
int main(void) {
char *str = "!count all the occurances of character in string!";
int i = 0;
char tempChar;
struct Node* head = NULL;
struct Node* node = NULL;
struct Node* first = NULL;
for(i = 0; i < strlen(str); i++)
{
tempChar = str[i];
head = first;
if(head == NULL)
{
node = (struct Node*)malloc(sizeof(struct Node));
node->data = tempChar;
node->counter = 1;
node->next = NULL;
if(first == NULL)
{
first = node;
}
}
else
{
while (head->next != NULL) {
if(head->data == tempChar)
{
head->counter = head->counter + 1;
break;
}
head = head->next;
}
if(head->next == NULL)
{
if(head->data == tempChar)
{
head->counter = head->counter + 1;
}
else
{
node = (struct Node*)malloc(sizeof(struct Node));
node->data = tempChar;
node->counter = 1;
node->next = NULL;
head->next = node;
}
}
}
}
printLinkList(first);
return 0;
}
回答by Vijay Kalathiya
Have checked that many of the answered are with static array, what if suppose I have special character in the string and want a solution with dynamic concept. There can be many other possible solutions, it is one of them.
已经检查过许多答案都是静态数组,如果假设我在字符串中有特殊字符并且想要一个具有动态概念的解决方案怎么办。可以有许多其他可能的解决方案,它就是其中之一。
here is the solutions with the Linked List.
这是链接列表的解决方案。
/* C Program to count the frequency of characters in a given String */
#include <stdio.h>
#include <string.h>
const char letters[] = "abcdefghijklmnopqrstuvwxzy";
void find_frequency(const char *string, int *count);
int main() {
char string[100];
int count[26] = { 0 };
int i;
printf("Input a string: ");
if (!fgets(string, sizeof string, stdin))
return 1;
find_frequency(string, count);
printf("Character Counts\n");
for (i = 0; i < 26; i++) {
printf("%c\t%d\n", letters[i], count[i]);
}
return 0;
}
void find_frequency(const char *string, int *count) {
int i;
for (i = 0; string[i] != '##代码##'; i++) {
p = strchr(letters, string[i]);
if (p != NULL) {
count[p - letters]++;
}
}
}
回答by Pratik Patil
Here is the C code with User Defined Function:
这是带有用户定义函数的 C 代码:
##代码##
