使用C++删除重复项并计算文本文件中的重复项



我是C++的初学者。我创建了一个包含两列的文本文件。但是,大约有 100 万行,并且有许多行相互重复。我想删除重复项并计算有多少重复项使其进入第三行。这是它之前和之后的样子:

以前:

10 8

11 7

10 8

10 8

15 12

11 7

后:

10 8 3

11 7 2

15 12 1

我真的不知道从哪里开始,有人可以指出我应该查找的正确方向才能做到这一点吗?

您可以创建std::map<std::pair<int, int>, int>,并在每次插入后检查给定的pair是否包含在map中。如果包含pair,则只需增加重复项的数量,否则将其放在map中。

像这样:

#include <iostream>
#include <map>
int main(int argc, char* argv[]) {
std::map<std::pair<int, int>, int> rows;
int num1;
int num2;
while (std::cin >> num1 >> num2) {
auto pair = std::make_pair(num1, num2);
if (rows.find(pair) != rows.end())
++rows[pair];
else
rows.emplace(pair, 1);
}
}
#include <string>
#include <fstream>
#include <unordered_map>
using namespace std;
int main()
{
string line;
unordered_map<string, int> count_map;
ifstream src("input.txt");
if (!src.is_open())
{
return -1;
}
while (getline(src, line))
{
if (line.empty())
continue;
count_map[line]++;
}    
src.close();
ofstream dst("output.txt");
if (!dst.is_open())
{
return -2;
}
for (auto & iter : count_map)
{
dst << iter.first << " " << iter.second << endl;
}
dst.close();
return 0;
}
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <set>
using namespace std;
int main() {
ifstream src("input.txt");
if (!src.is_open()) {
return -1;
}
// store each line, filter out all of duplicated strings
set<string> container;
// key is to maintain the order of lines, value is a pair<K, V>
// K is the itor pointed to the string in the container
// V is the counts of the string
map<int, std::pair<set<string>::iterator, int>> mp;
// key is the pointer which points to the string in the container
// value is the index of string in the file
map<const string *, int> index; 
string line;
int idx = 0; // index of the string in the file
while (getline(src, line)) {
if (line.empty()) {
continue;
}
auto res = container.insert(line);
if (res.second) {
index[&(*res.first)] = idx;
mp[idx] = {res.first, 1};
idx++;
} else {
mp[index[&(*res.first)]].second += 1;
}
}
src.close();
ofstream dst("output.txt");
if (!dst.is_open()) {
return -2;
}
for (const auto & iter : mp) {
dst << *iter.second.first << " " << iter.second.second << endl;
}
dst.close();
return 0;
}

顺便说一句,如果允许您使用它,Redis 可以轻松解决此问题。

这可以通过std::priority_queue来完成,它会自动对条目进行排序。像这样排序数据后,只需计算后续相同条目的数量:

#include <queue> 
#include <iostream>
#include <vector>
#include <utility> // for std::pair
int main() {
std::priority_queue<std::pair<int,int>> mydat;
mydat.push(std::make_pair(10,8));
mydat.push(std::make_pair(11,7));
mydat.push(std::make_pair(10,8));
mydat.push(std::make_pair(10,8));
mydat.push(std::make_pair(15,12));
mydat.push(std::make_pair(11,7));
std::vector<std::vector<int>> out;
std::pair<int,int> previous;
int counter;

while(!mydat.empty()) {
counter = 1;
previous = mydat.top();
mydat.pop(); // move on to next entry
while(previous == mydat.top() && !mydat.empty()) {
previous = mydat.top();
mydat.pop();
counter++;
}
out.push_back({previous.first, previous.second, counter});
}
for(int i = 0; i < out.size(); ++i) {
std::cout << out[i][0] << " " << out[i][1] << " " << out[i][2] << std::endl;
}
}

神博尔特演示

输出:

15 12 1 
11 7 2 
10 8 3

最新更新