我试图通过使用地图容器作为数据结构来定义一个名为Frequency的类。该类旨在从键盘读取字符并计算已输入的每个字符的频率。
这显示了频率类的UML图。 函数printFreqTable应该输出每个输入字符的频率,如示例输出所示:
Enter your string without spaces: textEPF
Char Frequency
E *
P *
F *
t **
e *
x *
但是,我的实现未产生任何输出,并且存在代码-1073741819。我还想知道是否有使用地图容器的更有效的实现方法。
#include <iostream>
using namespace std;
#include <map>
#include <string>
#include <vector>
class Frequency {
public:
Frequency();
void insertStringtoMap();
void printFreqTable();
void readString();
private:
typedef map <char, string, less <char > > mid;
mid CMap;
string s;
};
Frequency::Frequency()
{
readString();
}
void Frequency::readString()
{
cout << "Enter your string without spaces: ";
getline(cin, s);
cout << endl;
}
void Frequency::insertStringtoMap()
{
int si = s.size();
char str[50];
strcpy_s(str, s.c_str());
string freq = 0;
for (char ch = 65; ch <= 122; ch++) {
int c = 0;
for (int i = 0; i < si; i++)
{
if (ch == str[i])
{
c++;
}
}
if (c > 0)
{
for (int star = 0; star < c; star++)
{
freq = freq + "*";
}
CMap.insert(mid::value_type(ch, freq));
}
}
}
void Frequency::printFreqTable()
{
cout << "Char\tFrequency";
for (auto iter = CMap.cbegin(); iter != CMap.end(); ++iter)
{
cout << iter->first << "\t"
<< iter->second << "\n";
}
}
int main()
{
Frequency f;
f.insertStringtoMap();
f.printFreqTable();
}
答案 0 :(得分:0)
我已改为计算每个字符的出现,而不是直接构建图形表示。计数完成后,我使用了std :: string的功能来创建带有n个特定字符副本的字符串,以创建图表。
#include <iostream>
#include <map>
#include <string>
#include <vector>
class Frequency {
public:
Frequency();
void insertStringtoMap();
void printFreqTable();
void readString();
private:
typedef std::map<char, size_t> mid;
mid CMap;
std::string s;
};
Frequency::Frequency() :
CMap(),
s()
{
readString();
}
void Frequency::readString()
{
std::cout << "Enter your string without spaces: ";
std::getline(std::cin, s);
std::cout << std::endl;
}
void Frequency::insertStringtoMap() {
for(auto ch : s) {
++CMap[ch];
}
}
void Frequency::printFreqTable()
{
std::cout << "Char\tFrequency\n";
for (const auto& e : CMap)
{
std::cout << e.first << "\t" << std::string(e.second, '*') << "\n";
}
}
int main()
{
Frequency f;
f.insertStringtoMap();
f.printFreqTable();
}
答案 1 :(得分:0)
您的代码存在三个问题。
第一:
string freq = 0; //Assigning an int literal to a string?
它应该简单地是:
string freq;
第二:
这应该在for
旁边的第一个int c = 0;
循环中,以便您重置每个字符的*
s个计数。
for (char ch = 65; ch <= 122; ch++) {
int c = 0;
string freq;
第三:
只是为了使输出看起来更好,在此语句中添加新行,如下所示:
cout << "Char\tFrequency\n";
输出:
Enter your string without spaces: asdsadfkdfgag
Char Frequency
a ***
d ***
f **
g **
k *
s **
作为一个好习惯,请停止使用using namespace std
。请参阅此问题及其答案:Why is "using namespace std" considered bad practice?
答案 2 :(得分:0)
我认为您一次尝试做太多事情而感到困惑。
将问题分为两部分:读取字符串并将每次出现的事件存储在地图中,并以漂亮的格式打印结果地图。
现在,您可以轻松地将字符串解析到地图中,只需循环遍历每个字符并向地图添加一个条目-可以是任何东西,因此std::map<char, int>
将针对每个字符串存储一个int(即出现次数)键输入,可以是字符本身
通过解析地图条目并增加值来做到这一点,例如mymap[letter]++
或mymap.find(letter) += 1
然后通过遍历地图,打印与int值相同数量的星星来进行格式化。
(以伪代码:)
std::map<char,int>::iterator i = mymap.begin()
while (i != mymap.end()) {
cout i.first << "*" (i.second) times << endl;
i++;
}
不要在地图上存储*字符串,只需记下出现的次数,并在需要时使用它生成星号即可。这样效率更高,而且您也可以非常轻松地更改格式。
注意:在地图上使用typedef,这会使外观和读取更加容易。 Std :: string具有一个构造函数,可以轻松地在字符串中生成许多星星。