如果有数组,
int amounts[26] = { 0, 0, 0, ...};
,并且我希望数组的每个数字代表一个不同字符串的数量,以便在给定字符串中找到的amounts[0] = amount;
中的'a'
中的任何一个都可以递增每个值不使用if语句?
伪代码示例:
int amounts[26] = { 0, 0, 0, ...};
string word = "blahblah";
loop here to check and increment amounts[0] based on amount of 'a's in string
repeat loop for each letter in word.`
在循环结束时,基于字符串单词,金额应如下:
amounts[0] = 2 ('a')
amounts[1] = 2 ('b')
amounts[2] = 0 ('c')
// etc
答案 0 :(得分:5)
Given your example, assuming the entire string is lowercase and valid characters, there's a fairly simply solution (that is to say, you handle the validation)
for (int i = 0; i < word.size(); i++) {
amounts[word[i]-'a']++; // you can also do a pre-increment if you want
}
答案 1 :(得分:1)
What you want:
const char char_offset = 'a';
const int num_chars = 26;
std::vector<int> amounts(num_chars, 0);
std::string word = "blahblah";
for (auto c : word) {
int i = c - char_offset;
// this if statement is only for range checking.
// you can remove it if you are sure about the data range.
if (i >= 0 && i < num_chars) {
++amounts[i];
}
}
for (int i = 0; i < (int)amounts.size(); ++i) {
std::cout << (char)(char_offset + i) << ": " << amounts[i] << std::endl;
}
Output
a: 2
b: 2
c: 0
d: 0
e: 0
f: 0
g: 0
h: 2
i: 0
j: 0
k: 0
l: 2
m: 0
n: 0
...
答案 2 :(得分:1)
Use std::unordered_map< std::string, int >. Note that std::unordered_map< char, int > would be more efficient if only a single character is required. std::string allows counting complex strings (e.g. map["substring"]++ )
Maps can be accessed using bracket notation ( e.g. map[index] ), and thus can effectively remove the need for if statements.
#include <string>
#include <unordered_map>
#include <iostream>
int main()
{
std::unordered_map< std::string, int > map = { {"a",0} };
map["a"] += 1;
std::cout << map["a"];
}
答案 3 :(得分:1)
The following has quite some chances of being one of the fastest in matters of counting:
std::array<unsigned int, (1U << CHAR_BIT)> counts({ });
for(auto c : word)
counts[c]++;
Getting individual values is quite efficient:
std::cout << "a: " << counts['a'] << std::endl
Iterating over the letters - well, will require a little trick:
for(char const* c = "abcdefghijklmnopqrstuvwxyz"; *c; ++c)
// case-insensitive:
std::cout << *c << ": " << counts[*c] + counts[toupper(*c)] << std::endl;
Sure, you are wasting a bit of memory - which might cost you the performance gained again: If the array does not fit into the cache any more...
答案 4 :(得分:1)
一个通用的便携式解决方案是
const std::string alphabet = "abcdefghijklmnopqrstuvwxyz";
for (int i = 0; alphabet[i]; ++i)
amounts[i] = std::count(word.begin(), word.end(), alphabet[i]);
如果您可以假设小写字母的集合是一个连续范围,则可以简化为
for (char c = 'a'; c <= 'z'; ++c)
amounts[c - 'a'] = std::count(word.begin(), word.end(), c);
上面没有(公开)if
。当然,没有什么可以阻止std::count()
的实现。