数据去重

hybest007 2009-06-22 11:41:14
比如数据:1 2 3 3 4 5 5 5

可用何种方法产生:
1 2 3 4 5

我所想到的是用map,map有自动去重功能。但map有限制,数据量上千万后,map应该装不下了吧?除此之外还有什么方法?
...全文
349 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
zlp_ghost 2009-08-16
  • 打赏
  • 举报
回复
#include <iostream>
#include <queue>
using namespace std;
main()
{

int array2[10] = {1,1,2,3,3,3,4,4,5,5};
queue<int> array1;

for(int i = 0; i < 10; i++)
{
bool flag = true;
int ArrayVal = array2[i];
for(int j = i+1; j < 10; j++)
{
if(array2[j] == ArrayVal)
flag = false;
}

if(flag == true)
array1.push(ArrayVal);

}
int j=array1.size();
for(int i = 0; i < j; i++)
{
cout<<array1.front()<<",";
array1.pop();
}

cin.get();
}
limit_clear 2009-08-11
  • 打赏
  • 举报
回复
试验下结贴后
Dancing_Sea 2009-07-08
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 yangyunzhao 的回复:]
排序的开销太大了吧?
应该用容器
[/Quote]

你以为容器对这种情况是怎么实现的?

最好
1、hash方法
2、qsort,然后去重

如果是整形,知道确切上限,并且不是很大,标记位最佳——实际也是hash方法
justdo2008 2009-07-07
  • 打赏
  • 举报
回复
/**
* 字符串去重
* @param str 需要去重的字符串
* @param regex 分隔符
* @return
*/
public String removeDuplicates(String str,String regex){
String [] arr = str.split(regex);
Set strSet = new HashSet();
CollectionUtils.addAll(strSet, arr);
Object obj[] = strSet.toArray();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < obj.length; i++) {
sb.append(obj[i].toString());
sb.append(regex);
}
return sb.substring(0, sb.length()-1);
}
lpf000 2009-06-24
  • 打赏
  • 举报
回复
貌似都是采用map的方法,应该是动态分配的吧
多少数据装不下?

萧霖 2009-06-24
  • 打赏
  • 举报
回复
学习之
  • 打赏
  • 举报
回复
假如数据的是限是50000,数据共100000个

bool a[50000];
int data[100000];
........//将数据读入
int i;
for(i = 0; i < 100000; ++i)
a[data[i]] = true; //上面写错了。
int buf[50000];
int j = 0;
for(i = 0; i < 50000; ++i)
if(a[i]) buf[j++] = i;
从buf[0]到buf[j]之间就是你要的数。

如果数据在文件中,那更好办
int r;
fscanf(infp,"%d",&r);
a[r] = true;
即可
如果结果写入文件,那也好办
for(i = 0; i < 50000; ++i)
if(a[i]) fprintf(outfp,"%d ",i);
  • 打赏
  • 举报
回复
假如数据的是限是50000,数据共100000个

bool a[50000];
int data[100000];
........//将数据读入
int i;
for(i = 0; i < 100000; ++i)
a[i] = true;
int buf[50000];
int j = 0;
for(i = 0; i < 50000; ++i)
if(a[i]) buf[j++] = i;
从buf[0]到buf[j]之间就是你要的数。
pathuang68 2009-06-23
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 pathuang68 的回复:]
引用楼主 hybest007 的帖子:
比如数据:1 2 3 3 4 5 5 5

可用何种方法产生:
1 2 3 4 5

我所想到的是用map,map有自动去重功能。但map有限制,数据量上千万后,map应该装不下了吧?除此之外还有什么方法?


绝对可以装得下,我试过的,至少1亿个整数是一点问题都没有的,
参考:STL中的map和multimap中的第3部分(用的是multimap,装载1亿条记录)
[/Quote]
sorry,记错了,试验是用了900w条数据。不过我想应该是可以装下的。
pathuang68 2009-06-23
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 mengde007 的回复:]
为什么装不下;一样能;
数据库也可以吧;我设置为关键字;
[/Quote]
赞:可以装下
否:用数据库的方式不妥,因为有重复,所以不可能将这个字段设为primary key。
pathuang68 2009-06-23
  • 打赏
  • 举报
回复
[Quote=引用楼主 hybest007 的帖子:]
比如数据:1 2 3 3 4 5 5 5

可用何种方法产生:
1 2 3 4 5

我所想到的是用map,map有自动去重功能。但map有限制,数据量上千万后,map应该装不下了吧?除此之外还有什么方法?
[/Quote]
绝对可以装得下,我试过的,至少1亿个整数是一点问题都没有的,
参考:STL中的map和multimap中的第3部分(用的是multimap,装载1亿条记录)
heroctf 2009-06-23
  • 打赏
  • 举报
回复
。。。。。。
容器中vector是自增长的。但是set和map就不是了
你可以用set<unsigned long>来处理啊!!!
yangyunzhao 2009-06-23
  • 打赏
  • 举报
回复
排序的开销太大了吧?
应该用容器
coreyao1988 2009-06-23
  • 打赏
  • 举报
回复
学习了~~~~
hybest007 2009-06-23
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 xteaj 的回复:]
无符号整数,用bool数组方法最好啦,bool a[8]也就占一个字节,比较节省内存的。而且各方面都快。
先排序也需要时间,一个一个比较也需要时间,用bool数组应该是最快的,但浪费了空间。以空间换时间。
[/Quote]

怎么用啊?
  • 打赏
  • 举报
回复
无符号整数,用bool数组方法最好啦,bool a[8]也就占一个字节,比较节省内存的。而且各方面都快。
先排序也需要时间,一个一个比较也需要时间,用bool数组应该是最快的,但浪费了空间。以空间换时间。
lqy05wx 2009-06-23
  • 打赏
  • 举报
回复
[Quote=引用楼主 hybest007 的帖子:]
比如数据:1  2  3  3  4  5  5  5

可用何种方法产生:
1  2  3  4  5

我所想到的是用map,map有自动去重功能。但map有限制,数据量上千万后,map应该装不下了吧?除此之外还有什么方法?

[/Quote]
论坛里面有很多这方面的讨论,如果对数据有一定的信息支持(至少知道最小和最大,是不是正整数)
如果满足可以用位图来做预处理,可以节省空间
hybest007 2009-06-23
  • 打赏
  • 举报
回复
map效率有点低,不用map还有什么可行方案吗?
pathuang68 2009-06-23
  • 打赏
  • 举报
回复
下面用map的方式解决这个问题的代码(不考虑性能问题,只为了验证map可以装载1kw条记录),请大家指正:

1. 生成数据库文件程序,
2. 保证只有20个不重复的数字
3. 共1000w条记录

#include <iostream>
#include <fstream>
#include <string>
#include <time.h>
using namespace std;
// 生成info.txt的据程序
// info.txt中有1000万行数据
int main ()
{
char buffer[28];
clock_t start, finish;
ofstream outfile ("info.txt");

// 获取写物理文件起始时钟周期
start = clock();
for(int i = 1; i < 10000000; i++)
{
sprintf(buffer, "%d\n", i%20); // 保证只有20个不重复的数据
outfile.write (buffer, strlen(buffer));
}
// 获取写文件结束时钟周期
finish = clock();
int interval = (finish - start) * 1000 / CLOCKS_PER_SEC;
cout << "写物理文件所花时间:" << interval << "ms" << endl; // 5828ms
outfile.close();

return 0;
}

写文件花了5828ms

下面是重上面生成的文本文件中读取数据并存入到map中:

#include <iostream>
#include <fstream>
#include <map>
#include <string>
using namespace std;
// 用map的方式解决
int main(void)
{
ifstream fin("info.txt");
if(!fin)
{
cout << "can not open file..." << endl;
}

// 创建map,第一个int做为key,第二个string作为value
map<int, string> linemap;
int intkey;
string strvalue = " ";
char linestring[26];
clock_t start, finish;

// 写入linemap起始时钟周期
start = clock();
while(fin)
{
// 读取info.txt的一行,存入linestring
fin.getline(linestring, 26);
intkey = atoi(linestring);

// 将key,value对存入map中
linemap.insert(pair<int, string>(intkey, strvalue));
}
// 写入linemap结束时钟周期
finish = clock();
fin.close();

cout << (finish - start) * 1000 / CLOCKS_PER_SEC << "ms elapsed." << endl; // 7360ms
// 检查数据被插入后,是否根据strkey排序了 -> 结论:排序了
// 即使info.txt中有重复的key,也只会有第一行含有key的文本,会被读入到map中

cout << linemap.size() << endl; // 20,即只有20个不重复的数据

map<int, string>::iterator p;
for(p = linemap.begin(); p != linemap.end(); ++p)
{
cout << p->first << endl;
}
return 0;
}

1. 需时7360ms
2. map中只有20个数字,而且是排好序的
3. 20个数字是0,1,2, ... 19

map的效率似有点不太好,不过承载1000w条记录还是没有问题的。
mabelsz 2009-06-23
  • 打赏
  • 举报
回复
加载更多回复(14)
内容概要:本文详细介绍了MySQL中InnoDB存储引擎的逻辑存储结构及其表分区技术。InnoDB的逻辑存储单元由高到低依次为表空间、段、区、页和行,其中表空间包括系统表空间、独立表空间、通用表空间、Undo表空间和临时表空间,每种表空间具有不同的用途和管理方式。文章进一步讲解了表分区的概念与类型,包括RANGE、LIST、HASH、KEY以及多字段COLUMNS分区,阐述了分区的优势如提升查询性能、便于数据维护、支持跨物理设备存储等,并列举了实际SQL操作示例,帮助理解分区表的创建、修改、删除及重组等操作。同时指出了分区的限制条件,如最大分区数量、主键约束要求等。; 适合人群:具备一定MySQL数据库基础,从事数据库开发、运维或架构设计的技术人员,尤其是工作中涉及大数据量表管理与性能优化的1-3年经验研发人员。; 使用场景及目标:①深入理解InnoDB存储机制,优化数据库物理结构设计;②掌握表分区技术,应用于海量数据存储与高效查询场景,如日志系统、订单系统的时间分区设计;③通过分区实现数据归档、快速删除历史数据、提升查询性能等运维目标; 阅读建议:学习时应结合MySQL实际环境动手实践文中提供的SQL命令,重点关注表空间管理和分区策略的选择,理解其对性能和维护的影响,并注意分区使用中的限制条件以避免设计失误。
内容概要:本文系统介绍了GitHub Copilot的实战使用技巧,涵盖其核心功能、提示工程、上下文管理、自定义配置及常见误区。文章强调Copilot不仅是代码补全工具,更是覆盖软件开发全生命周期的AI编程助手,重点讲解如何通过上下文工程、提示词结构化、斜杠命令与聊天参与者等方式提升代码生成质量,并结合实战案例展示在测试生成、代码重构、调试、文档编写等场景中的高效应用。同时指出Copilot的局限性,倡导“人为主导、AI辅助”的协作模式,强调代码审查与安全合规的重要性。; 适合人群:具备一定编程经验,希望提升开发效率的个人开发者、团队工程师及技术管理者,尤其是正在使用或计划引入AI编程工具的研发人员。; 使用场景及目标:①掌握Copilot在测试生成、代码解释、重构优化、调试排错等方面的高级用法;②学会构建高质量提示词与自定义指令,使AI输出更贴合项目规范;③规避常见使用陷阱,实现安全、可控、高效的AI辅助开发。; 阅读建议:此文档兼具理论指导与实操示范,建议结合实际开发环境边学边练,重点关注提示工程、上下文管理与自定义指令配置,持续迭代优化使用方式,并在团队中建立统一的AI编码规范与审查机制。

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧