如何以降序打印字符串中每个字母的频率c ++?

时间:2018-06-24 03:37:46

标签: c++ string

#include <iostream>
#include <string>
using namespace std;
int main () {
    int cnt[26] {};
    char alpha[26];
        string s = "abcdefffggghiii";
        for (int i = 0; i < s.length(); i++) {
                cnt[s[i] - 'a']++;
        }

    for (int i = 'a'; i <= 'z'; i++) {
        alpha[i - 'a'] = i;
    }
    for (int i = 0; i < 26; i++) {
        if (cnt[i]) {
            cout << alpha[i] << " " << cnt[i] << endl;
        }
    }

    return 0;
}

我想按降序打印字符串中每个字母的频率。我曾经考虑过对cnt数组进行排序并从250打印,但是它只会打印错误字母的频率。如何解决它以降序打印例如i 3等问题?

3 个答案:

答案 0 :(得分:3)

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

int main() {

  // Create result container    
  auto x = vector<pair<char, int>>();

  std::string s = "abcdefffggghiii";
  for (auto& l : s) {    
    // Find the item that corresponds to letter
    auto pLetter =
        find_if(x.begin(), x.end(), [&l](pair<char, int> &arg) {
          return arg.first == l;
        });

    if (pLetter != x.end())
      pLetter->second++;   // If item corresponding to letter is found, increment count
    else {
      x.push_back(make_pair(l, 1)); // Otherwise, create a new result entry
    }
  }

  // Sort results by count in descending order
  std::sort(x.begin(), x.end(),
            [](auto &left, auto &right) { return left.second > right.second; });

  for (auto i = x.begin(); i != x.end(); ++i)
    std::cout << i->first << ':' << i->second << '\n';
}

生产

f:3
g:3
i:3
a:1
b:1
c:1
d:1
e:1
h:1

您可以here运行它。这使用C ++ 14 lambda作为find_if和sort谓词。此解决方案与@Retired Ninja的解决方案非常相似,不同之处在于结果向量仅包含那些计数为非零的字母的项目。这意味着它可以扩展到wstrings,而无需较大的结果向量。

答案 1 :(得分:2)

这就是我可能要做的。您只需要将字母和数量保持在一起即可。

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

struct LetterFreq
{
    char letter;
    int freq;
};

int main()
{
    std::vector<LetterFreq> cnt(26);
    for (size_t i = 0; i < cnt.size(); ++i)
    {
        cnt[i].freq = 0; 
        cnt[i].letter = static_cast<char>(i) + 'a';
    }
    std::string s = "abcdefffggghiii";
    for (auto& l : s)
    {
        cnt[l - 'a'].freq++;
    }
    std::sort(cnt.begin(), cnt.end(), [](const LetterFreq& lhs, const LetterFreq& rhs) 
    { 
        return lhs.freq > rhs.freq; 
    });
    for (auto& item : cnt)
    {
        if (item.freq == 0)
        {
            break;
        }
        std::cout << item.letter << " : " << item.freq << "\n";
    }
    return 0;
}

如果全部都用小写ASCII字母,这很简单。对于更复杂的输入,您可以使用相同的字母概念并在结构中计数,但是您可能希望将向量的大小增加到256以跟踪所有可能性,或者使用诸如无序映射的内容存储使用过的符号,然后将其复制到可以分类显示的容器中。您还可以使用并行数组,并在交换计数的同时排序交换字母位置。有很多方法可以解决这个问题。

答案 2 :(得分:0)

您可以使用配对,但是看起来您正在使用更多基本类型。在这种情况下,您可能必须使用嵌套循环。继续查找频率最高的字符,将其打印,然后将其频率设置为-1,以表明您已经对其进行了处理。