阵列初始化并找到字母频率

Array initialization and finding letter frequency

本文关键字:频率 初始化 阵列      更新时间:2023-10-16

我正在尝试计算字符串数组中的字母频率,并将频率设置为整个字母的大小数组。我希望我已经设计了方式,所以上/下案件无关紧要。之后,我想将最高频率字母设置为该字母的" e"(因为e以多种语言中的频率最高),并找到最频繁的字母和e之间的差异。在我的心理演练中,这似乎是有道理的,但是由于某种原因,我的编译器给了我断点,并且根本不允许我检查它,所以我不确定怎么了。因此,请原谅我不发布SSCCE。在此先感谢您的帮助!

#include <iostream>
#include <fstream> 
using namespace std;
int main()
{
    int alpharay[26]; 
    for (int i = 0; i < 26; i++) 
    {
        alpharay[i] = 0;
    }
    ifstream input; 
    cout << "File name (.txt): ";
    string fileName;
    cin >> fileName;
    input.open(fileName.c_str()); 
    while (!input.eof())
    {
        string newLine;
        getline (input, newLine); 
        for (int i = 0; i < newLine.length(); i++)
        {
            if (isalpha(newLine[i]))
            {
                int index;
                if (isupper(newLine[i]))
                {
                    index = newLine[i] - 'A';
                    alpharay[index]++; 
                }
                else if (islower (newLine[i]))
                {
                    index = newLine[i] - 'a'; 
                    alpharay[index]++; 
                }
            }
        }
    }
    //To find the largest value in array
    int largest = 0;
    char popular;
    for (int i = 0; i < 26; i++)
    {
        if (alpharay[i]>=largest)
        {
            largest = alpharay[i]; 
            popular = 'a' + i; 
        }
    }
    //To find the size of the shift
    int shift = popular - 'e';
    cout << "Shift size: " << shift << endl;
    return 0;
}

问题1:

input.open(fileName.c_str()); 
while (!input.eof())

需要检查以查看文件是否打开。如果文件未打开,您将永远不会获得EOF。

input.open(fileName.c_str()); 
if (input.is_open()
{
    while (!input.eof())
    // rest of your code
}
else
{
    cout << "Couldn't open file " << fileName << endl;
}

,但这只是绷带问题。文件对文件可能发生的更多,而不仅仅是您需要注意的EOF。

问题2:

while (!input.eof())
{
    string newLine;
    getline (input, newLine); 
    for (int i = 0; i < newLine.length(); i++)

那么,如果Getline阅读EOF怎么办?该程序将其处理为有效行,然后对EOF进行测试。同样,一个简单的修复程序:

string newLine;
while (getline (input, newLine))
{
    for (int i = 0; i < newLine.length(); i++)
    // rest of loop code
}

只要读取行,请继续前进。如果没有线,无论为什么,循环退出。

问题3:

如果没有alpha字符,此循环将返回'z':

for (int i = 0; i < 26; i++)
{
    if (alpharay[i]>=largest)
    {
        largest = alpharay[i]; 
        popular = 'a' + i; 
    }
}

简单的解决方案是运行循环,然后测试最大== 0并打印合适的"未找到字母"消息。

在C 中,我们不应使用C风格数组,而应使用C STL容器。并且有许多用于各种目的的容器。

例如计算元素。

或多或少有一种标准方法来计算容器或一般的内容。

我们可以使用std::mapstd::unordered_map等关联容器。在这里,我们将"键"相关联,在这种情况下,在这种情况下,在这种情况下,在这种情况下是特定字母的数量。

幸运的是,这些地图有一个非常不错的索引运算符[]。这将寻找给定的键,如果发现,请返回对该值的引用。如果找不到,它将创建一个带有钥匙的新条目,并返回对新条目的引用。因此,在机器人情况下,我们将参考用于计数的值。然后我们可以简单地写:

std::unordered_map<char,int> counter{};
counter[c]++;

看起来真的很直观。

另外。从地图中获取最大的反价值,可以通过使用Maxheap来实现。可以使用std::priority_queue在C 中实现Maxheap。您可以使用其范围构造函数,以填充std::unordered_map的值。因此,典型的单线。现在您可以立即访问最高价值的最高价值。

这样,我们可以得到一个非常紧凑的代码。

#include <iostream>
#include <fstream>
#include <utility>
#include <unordered_map>
#include <queue>
#include <vector>
#include <iterator>
#include <string>
#include <cctype>
// Some Alias names to ease up typing work and to make code more readable
using Counter = std::unordered_map<char, int>;
struct Comp { bool operator ()(const std::pair<char, int>& p1, const std::pair<char, int>& p2) { return p1.second < p2.second; }};
using MaxHeap = std::priority_queue<std::pair<char, int>, std::vector<std::pair<char, int>>, Comp>;
int main() {
    // Get filename, open file and check, if it could be opened
    if (std::string fileName{}; std::getline(std::cin, fileName)) {
        if (std::ifstream fileStream{ fileName }; fileStream) {
            Counter counter{};
            // Read all characters from the source file and count their occurence
            for (char c{}; fileStream >> c;) {
                // Get lower case of letter
                const char letter = static_cast<char>(std::tolower(c));
                // Count occurence, if letter is an alpha value
                if (std::isalpha(letter)) counter[letter]++;
            }
            // Build a Max-Heap
            MaxHeap maxHeap(counter.begin(), counter.end());
            // Show result
            std::cout << "nShift size: " << maxHeap.top().first-'e' << 'n';
        }
        else std::cerr << "nError: Could not open file '" << fileName << "'n";
    }
}

用C 17

编译

用于轻松以排序顺序访问所有元素,您也可以使用std::multiset而不是std::priority队列。

,如果您只想具有最高元素,则可以与std::partial_sort_copy一起使用CC_7。