【问题标题】:Is There an Efficient Method of Checking Which Letter is Being Used?是否有一种有效的方法来检查正在使用的字母?
【发布时间】:2021-10-06 01:39:48
【问题描述】:

假设我有一个字符串string str;,其中包含任意数量的字母,我想计算字符串中每个字母的数量。例如,单词"Example" 有2 个'e'、1 个'x'、1 个'a'、1 个'm'、1 个'p' 和1 个'l'。有没有比这更有效的方法来检查每个字母?

for (int i = 0; i < str.length(); i++)
{
    if (str.at(i) == 'a')
    {
        //variable which keeps track of a ++
    }...
    //25 more of that for each other letter
}

感觉必须有一种更有效的方法来做到这一点,但我不知道怎么做。请赐教。

【问题讨论】:

  • 使用数组大小​​为 ascii 表的大小,然后您可以轻松计算每个字符。数组[字符]++
  • 或者更确切地说是array[(unsigned char)character],因为chars 可能会签名也可能不会签名。
  • 附带说明:在此示例中使用at() 是多余的,因为for 循环确保它不会超出字符串的范围,因此无需对每个范围进行检查特点。使用str[i] 而不是str.at(i)
  • @Wahalez -- 关闭,但使用char 可以容纳的可能值的数量,即1u &lt;&lt; CHAR_BIT。计数时字符编码无关紧要。

标签: c++ string letter


【解决方案1】:

例如,您可以使用std::map

#include <map>

std::map<char, std::size_t> mCount{};
for (auto ch : str)
{
   ++mCount[ch];
}

使用std::array(它的优点是数据在内存中是连续的,从而提高了缓存性能)你可以这样写:

#include <array>
#include <limits>

constexpr auto nNumChars = static_cast<std::size_t>(std::numeric_limits<unsigned char>::max()) + 1;
std::array<std::size_t, nNumChars> arCounts{};

for (auto ch : str) {
   ++arCounts[static_cast<unsigned char>(ch)];
}

【讨论】:

  • 您可能希望将数组大小增加到256
  • 仅当 char 未签名时。否则,负字符上有 UB
  • 一个 256 个数组,将 ch 转换为一些 unsigned 会使您的数组答案非常出色。
  • 为了可移植性,我认为数组大小需要为(2 &lt;&lt; CHAR_BIT) - 1。这将涵盖char 大于 8 位的情况。
  • @NathanOliver 即使CHAR_BIT 是 64 也会有问题 :-)(顺便说一句,你的意思是 1 &lt;&lt; CHAR_BIT 对)?
【解决方案2】:

为此我特别喜欢multisets

string 初始化是直接的。

走布景不是那么干净。

https://godbolt.org/z/soccz8Tnn

#include <iostream>
#include <set>
#include <string>

int main()
{
    std::string str{"The quick fox jumped over the green fence"};

    // Easy initialization from string
    std::multiset<char> st(cbegin(str), cend(str));

    // Printing the count for each different key is a bit more difficult
    for (auto it{cbegin(st)}; it != cend(st); it = st.upper_bound(*it))
    {
        std::cout << "st[" << *it << "] = " << st.count(*it) << "\n";
    }
}

【讨论】:

  • 它不是为每个字符执行堆分配吗? (任何字符,不仅是唯一字符):(
  • @HolyBlackCat 我不确定,但很容易就是这样,是的。我将 OP 对效率的引用理解为避免编写 26 个 if 块;而且,从这个意义上说,multiset 几乎是不可战胜的。但我同意array 解决方案并不复杂,而且确实更有效(对于插入/查找/内存使用)。
猜你喜欢
  • 2019-05-13
  • 2020-04-14
  • 1970-01-01
  • 2014-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多