有没有一种替代方法可以在不使用if语句的情况下有条件地递增数组值? C ++

时间:2019-01-18 18:06:17

标签: c++ arrays loops

如果有数组,

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

5 个答案:

答案 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()的实现。