阵列初始化并找到字母频率
Array initialization and finding letter frequency
我正在尝试计算字符串数组中的字母频率,并将频率设置为整个字母的大小数组。我希望我已经设计了方式,所以上/下案件无关紧要。之后,我想将最高频率字母设置为该字母的" 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::map
或std::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。
- 是否可以初始化不可复制类型的成员变量(或基类)
- C++使用整数的压缩数组初始化对象
- C++初始化基类
- 多成员Constexpr结构初始化
- 复制列表初始化的隐式转换的等级是多少
- 内联映射初始化的动态atexit析构函数崩溃
- 如何在C++中初始化嵌套类中的2个memeber
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 没有用于初始化C++中的变量模板的匹配构造函数
- 在未初始化映射的情况下,将值插入到映射的映射中
- C++成员初始化
- 为什么在C++中首先初始化成员类
- 同时具有"聚合初始化"和"模板推导"
- 初始化具有非默认构造函数的std::数组项的更好方法
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 在C和C++中初始化结构中的数组
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 在函数内部的声明中初始化数组,并在外部使用它
- 阵列初始化并找到字母频率