2016-05-13 754 views
-1
void main() 
{ 
string s, Letter; 
cin >> s; 
int count[26], i, s_i; 
for (i = 0; i < 26; i++) 
    count[i] = 0; 
int n = sizeof(s); 
for (i = 0; i < n; i++) 
{ 
    s_i = s[i] - 'a'; 
    count[s_i]++; 
} 
for (i = 0; i < 26; i++) 
{ 
    if (count[i] != 0) 
    { 
     Letter = 'a' + i; 
     cout << Letter << " : " << count[i] << endl; 
    } 
} 
} 

这是一个程序来计算字符串的字母数。 s_i = s [i] - 'a'是什么意思?特别是,为什么使用 - 'a'?有没有其他方法来计算字母?s_i = s [i] - 'a'是什么意思?

+1

想一下“a” - “a”是什么意思。那么,'b' - 'a''意味着什么。 –

+0

'a'+ 1 ='b','a'+ 2 ='c' – tofutim

+2

s_i = s [i] - 'a'。这用于从0开始获取索引。这里简单地说明了两个字符的ASCII值的区别。 '''表示s_i = 98(字符'b'的ASCII值) - 97(字符'a'的ASCII值)= 1 –

回答

1

表达式x - 'a'为您提供了x中的字符值与字母表的第一个小写字母之间的距离。

例如:
'B' - 'A' == 1
'C' - 'A' == 2

编辑1:更简单的方法
声明你的计数阵列拥有256个插槽。
使用该字符作为数组的索引。
增加索引处的值。

例如:

unsigned int counts[256]; 
char c = 'b'; 
//... 
counts[c] += 1; 

使用减法,x - 'a'允许较小尺寸数组。

编辑2:更多的便携式解决方案
一个更通用的解决方案,一个不依赖于编码方式,是使用含有字母字符的阵列。搜索字符,如果找到,索引就是字符的偏移量。

char c = 'j'; 
const std::string lowercase_alphabet = "abcdefghijklmnopqrstuvwxyz"; 
const std::string uppercase_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
unsigned int counts[26] = {0}; 
//... 
unsigned int index = lowercase_alphabet.find(c); 
if (index != std::string::npos) 
{ 
    ++counts[index]; 
} 
else 
{ 
    index = uppercase_alphabet.find(c); 
    if (index != std::string::npos) 
    { 
    ++counts[index]; 
    } 
} 

相同的概念可以应用于字符数组而不是std::string类型。

注意:touppertolower函数不用于避免本地化开销。

+0

你的意思是26个插槽,而不是256个? – CinCout

+0

要迂腐,“c” - “a'== 2”等不能保证是正确的,例如[EBCDIC](http://www.csgnetwork.com/ascebcdic.html); C标准只保证IIRC,即'a'<'b'<'c'<... –

+0

@CinCout:不,数组是256个时隙,是'char'类型的范围。该方法很简单,因为它不需要减法。使用字符变量作为数组的索引。 –

0

很少有一点要注意:

  1. 程序假定字符串包含只有小写字母(A-Z),别无其他。因此,可以在最大26 possible character[a-z]

  2. 这样做-'a',我们只是减去s[i]'a' ASCII值。每个角色都有独特的ascii value。编译期间,编译器检查'a'的ascii值,并用-48替换-'a'。我们可以完成-48,而不是在做-'a',但在这种情况下,我们不需要记住'a'的ascii值。

  3. [a-z]的所有ascii值都是连续的。 a's的值是48,z's的值是57.因此,通过做s[i]-'a',我们知道ith varaiblea有什么不同。

  4. 最后Letter = 'a' + i;完成获取原始字符。