使用字符串中的 2 个键填充地图。字符和频率 c++
我是地图新手,所以有点不确定执行此操作的最佳方法。该任务与霍夫曼编码压缩有关。这是我所拥有的。
#include <map>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
typedef map<char,int> huffmanMap;
void getFreq(string file, map<char, int> map)
{
map.clear();
for (string::iterator i = file.begin(); i != file.end(); ++i) {
++map[*i];
}
}
上面是我在网上找到的一种方法,但无法打印
int main()
{
map<char, int> huffmanMap;
string fileline;
ifstream myfile;
myfile.open("text.txt",ios::out);
while(!myfile.eof()) {
getline(myfile, fileline); //get the line and put it in the fileline string
}
myfile.close();
我从文本文件中读取的任何内容以填充字符串文件行。
for (int i=0; i<fileline.length(); i++) {
char t = fileline[i];
huffmanMap[i]? huffmanMap[i]++ : huffmanMap[i]=1;
}
这是我尝试填充地图的第二种方法,字符值不正确,符号和笑脸。
getFreq(fileline,huffmanMap);
huffmanMap::iterator position;
for (position = huffmanMap.begin(); position != huffmanMap.end(); position++) {
cout << "key: \"" << position->first << endl;
cout << "value: " << position->second << endl;
}
这就是我尝试打印地图的方法
system("pause");
return 0;
}
当我运行 getFreq 方法时,程序崩溃了。我没有收到任何错误。使用第二种方法时, char 值是无意义的。注意,我没有同时运行这两种方法,我只是将它们都包含在内以显示我所尝试的内容。
任何见解将不胜感激。谢谢。对初学者要宽容一点;)
I am new to maps so an a little unsure of the best way to do this. This task is in relation to compression with huffman coding. Heres what I have.
#include <map>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
typedef map<char,int> huffmanMap;
void getFreq(string file, map<char, int> map)
{
map.clear();
for (string::iterator i = file.begin(); i != file.end(); ++i) {
++map[*i];
}
}
above is one method I found online but was unable to print anything
int main()
{
map<char, int> huffmanMap;
string fileline;
ifstream myfile;
myfile.open("text.txt",ios::out);
while(!myfile.eof()) {
getline(myfile, fileline); //get the line and put it in the fileline string
}
myfile.close();
I read in a from a text file to populate string fileline.
for (int i=0; i<fileline.length(); i++) {
char t = fileline[i];
huffmanMap[i]? huffmanMap[i]++ : huffmanMap[i]=1;
}
here is a second method I tried for populating the map, the char values are incorrect, symbols and smileyfaces..
getFreq(fileline,huffmanMap);
huffmanMap::iterator position;
for (position = huffmanMap.begin(); position != huffmanMap.end(); position++) {
cout << "key: \"" << position->first << endl;
cout << "value: " << position->second << endl;
}
This is how I tried to print map
system("pause");
return 0;
}
When I run my getFreq method the program crashes. I dont get any errors with either. With the second method the char values are nonsense.Note I have not had both methods running at the same time I just incuded them both to show what i have tried.
Any insight would be appreciated.Thanks. Be lenient im a beginner ;)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的代码到处都是,不是很连贯,因此很难理解流程。
以下是一些不足之处:
这是错误的:
myfile.open("text.txt",ios::out);
- 为什么要使用以下命令打开输入流out
标志?它应该简单地是:在 while 循环中,您想要做的是迭代内容并将其添加到您的地图中?所以现在代码看起来像:
下一步修复,这是错误的:你有一个 typedef 和一个同名的变量!
使用合理的命名
下一步修复,您的
getFreq
方法签名是错误的,您通过值(即复制)而不是引用传递地图,因此您在函数中的修改是复制品不是原件!错误:
void getFreq(string file, mapmap)
正确:
void getFreq(string file, huffmanMap_Type& map)
下一步: 为什么在上面的方法中使用
clear()
?如果有多于一根线怎么办?肯定不需要这个吧?现在就足够了,如果有更多问题,请清理您的代码并更新您的问题。
Your code is all over the place, it's not very coherent so difficult to understand the flow.
Here are some low-lights:
This is wrong:
myfile.open("text.txt",ios::out);
- why would you open an input stream without
flag? it should simply be:In the while loop, what you want to do is to iterate over the content and add it to your map? So now the code looks like:
Next fix, this is wrong: you have a typedef and a variable of the same name!
Use sensible naming
Next fix, your
getFreq
method signature is wrong, you are passing the map by value (i.e. copy) rather than reference, hence you modification in the function is to a copy not the original!wrong:
void getFreq(string file, map<char, int> map)
correct:
void getFreq(string file, huffmanMap_Type& map)
Next: why
clear()
in the above method? What if there is more than one line? No need for that surely?That's enough for now, clean up your code and update your question if there are more issues.
一项修复,一项改进。
修复是:在
getFreq
参考中创建第二个参数:改进是:只需写入
而不是
毕竟,通过写入
huffmanMap[i]?
你正在检查它是否为零。如果为零,则将其设为 1,这与 huffmanMap[i]++ 相同。One fix and One improvement.
Fix is : make second parameter in
getFreq
reference:Improvement is : just write
instead of
After all, by writing
huffmanMap[i]?
you're checking whether it's zero or not. If zero, then you make it one, which is same ashuffmanMap[i]++
.(使用 C++20 的 C++ 语言功能的答案。
但首先,您询问如何获取文本中字母的计数(频率)。
对此几乎有一种通用的解决方案。我们可以使用
std::unordered_map
中的 C++ 参考此处这是
std::unordered_map
非常方便的索引运算符[]
这使得计数变得非常简单。该运算符返回对映射到键的值的引用。因此,它搜索键,然后返回值。如果键不存在,它会插入一个新的键/值对并返回对该值的引用,因此,无论如何,都会返回对该值的引用,例如:
使用“std:”。 :unordered_mapmymap{};" 和文本“aba”,可以使用索引运算符完成以下操作:
mymap['a']++
,将插入一个新的gey/值对'a'/0,然后递增它,导致'a'/1等等。
通过使用一些现代语言元素,可以使用一个简单的
for
循环来读取整个文件并计算其字符数:附加信息:
为了构建一棵霍夫曼树,我们可以使用最小堆,它可以使用现有的 std::priority_queue 轻松实现。请阅读此处了解相关内容。
只需4行代码,就可以构建完整的霍夫曼树。
最后,我们将结果放入密码本中。再次使用
std::unordered_map
并将结果显示给用户。例如,这可以像下面这样实现:
您我注意到我们使用
new
来分配内存。但事后我们不会删除
它。我们现在可以在适当的位置添加删除语句,但我将向您展示使用智能指针的修改后的解决方案。
请看这里:
(An answer using C++ language features fom C++20.
But first, you were asking about getting getting the count (frequency) of letters in a text.
There is nearly a universal solution approach for this. We can use the
std::unordered_map
. It is described in the C++ reference here.It is the
std::unordered_map
s very convienient index operator[]
which makes counting very simple. This operator returns a reference to the value that is mapped to a key. So, it searched for the key and then returns the value. If the key does not exist, it inserts a new key/value pair and returns a reference to the value.So, in any way, a reference to the value is returned. And this can be incremented. Example:
With a "std::unordered_map<char, int> mymap{};" and a text "aba", the follwoing can be done with the index operator:
mymap['a']++
, wiil insert a new gey/value pair 'a'/0, then increment it, resulting in 'a'/1And so on and so on.
By using some modern language elements, a whole file can be read and its characters counted, with one simple
for
-loop:Additional information:
For building a Huffmann tree, we can use a Min-Heap, which can be easily implemented with the existing
std::priority_queue
. Please read here abour it.With 4 lines of code, the complete Huffmann tree can be build.
And the end, we put the result in a code book. Again a
std::unordered_map
and show the result to the user.This could zhen be for example implemented like the below:
You my notice that we use
new
to allocate memory. But we do notdelete
it afterwards.We could now add the
delete
statements at the approiate positions but I will show you a modified solution using smart pointers.Please see here: