这个程序从txt文件中读取数字字符串,将它们转换为整数,将它们存储在一个向量中,然后尝试以有组织的方式输出它们....
如果txt文件说:
7 5 5 7 3 117 5
程序输出:
3
5 3
7 2
117
所以,如果数字出现不止一次,它会输出发生的次数。这是迄今为止的代码。
#include "std_lib_facilities.h"
int str_to_int(string& s)
{
stringstream ss(s);
int num;
ss >> num;
return num;
}
int main()
{
cout << "Enter file name.\n";
string file;
cin >> file;
ifstream f(file.c_str(), ios::in);
string num;
vector<int> numbers;
while(f>>num)
{
int number = str_to_int(num);
numbers.push_back(number);
}
sort(numbers.begin(), numbers.end());
for(int i = 0; i < numbers.size(); ++i)
{
if(i = 0 && numbers[i]!= numbers[i+1]) cout << numbers[i] << endl;
if(i!=0 && numbers[i]!= numbers[i-1])
{
cout << numbers[i] << '\t' << counter << endl;
counter = 0;
}
else ++counter;
}
}
编辑:程序陷入困境。现在正在寻找无限循环。
答案 0 :(得分:8)
您可以使用数字地图来计数:
typedef map<int,unsigned int> CounterMap;
CounterMap counts;
for (int i = 0; i < numbers.size(); ++i)
{
CounterMap::iterator it(counts.find(numbers[i]));
if (it != counts.end()){
it->second++;
} else {
counts[numbers[i]] = 1;
}
}
...然后遍历地图以打印结果。
编辑: 正如lazypython所建议的那样:如果你有TR1 extensions [wikipedia.org],unordered_map应该有更好的表现......
typedef std::tr1::unordered_map<int,unsigned int> CounterMap;
CounterMap counts;
for (int i = 0; i < numbers.size(); ++i)
{
CounterMap::iterator it(counts.find(numbers[i]));
if (it != counts.end()){
it->second++;
} else {
counts[numbers[i]] = 1;
}
}
答案 1 :(得分:6)
如何使用地图,其中键是您要跟踪的数字,值是出现次数?
如果你必须使用矢量,你已经对它进行了排序。所以只需跟踪您之前看到的数字。如果它与当前数字相同,则递增计数器。每次号码更改时:打印出当前号码和计数,重置计数,将last_seen号码设置为新号码。
答案 2 :(得分:3)
使用地图是实用解决方案。你应该做的是解决这个问题:)
这称为频率计数器。所以,你有一个有序矢量,所有你需要做的就是计算连续相等的数字。换句话说,您必须检查每个号码及其后继号码。
for(size_t i = 0; i < numbers.size(); i++)
{
size_t count = 1;
size_t limit = numbers.size() - 1;
while(i < limit && numbers[i] == numbers[i+1])
{
count++;
i++;
}
std::cout << numbers[i] << "\t" << count << std::endl;
}
答案 3 :(得分:1)
该程序读取数字字符串 从txt文件中,将它们转换为 整数,将它们存储在矢量中,以及 然后尝试输出它们 如此有组织的时尚.... (强调添加)
此存储步骤的重点是什么?如果您正在读取文件中的数字,那么您已经按顺序将它们编号,准备好在遇到它们时一次处理(计数)。
但是,我需要一种方法让它知道什么时候会看到一个新号码。
我建议您查看std::set
或std::map
。我希望这些容器中的任何一个都可以满足您的需求。
答案 4 :(得分:1)
Std::count()
非常适合这项法案。
std::vector<int>::const_iterator cur = numbers.begin();
std::vector<int>::const_iterator last = numbers.end();
while (cur != last) {
unsigned cnt = std::count(cur, last, *cur);
std::cout << *cur;
if (cnt != 1) {
std::cout << " " << c;
}
std::cout << std::endl;
int saved = *cur;
while (*cur == saved) {
++cur;
}
}
当然还有很多其他算法可以完成同样的工作。与std::equal_range()
一起玩std::distance()
之类的东西就可以很好地完成工作。
答案 5 :(得分:0)
这很有趣:
#include <map>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>
struct IncrementMap
{
IncrementMap(std::map<int,int>& m): m_map(m) {}
void operator()(int val) const
{
++m_map[val];
}
std::map<int,int>& m_map;
};
struct SpecialPrint
{
SpecialPrint(std::ostream& s): m_str(s) {}
void operator()(std::map<int,int>::value_type const& value) const
{
m_str << value.first;
if (value.second != 1)
{
m_str << "\t" << value.second;
}
m_str << "\n";
}
std::ostream& m_str;
};
int main()
{
std::fstream x("Plop");
std::map<int,int> data;
std::for_each( std::istream_iterator<int>(x),
std::istream_iterator<int>(),
IncrementMap(data)
);
std::for_each( data.begin(),
data.end(),
SpecialPrint(std::cout)
);
}