有一种最直接的方法可以去掉一个集合中重复的元素,这种方法据说就是“交给下面去做”,然而有时候,你自己动手去做一下也是不错的。如果交给下面去做,最直接的选择就是使用map,在java中,我们有HashMap,TreeMap等等实现了map接口的类可用,c++中,同样有STL的同类集合可以使用,在各类高级语言中,就更不必说了,然而在c中,就没有那么幸运了,很多东西需要你来自己实现。

根据《C语言内力修炼与软件工程》,用c语言自行实现这个东西,其实对于软件工程而言没有必要,然而可以训练一下自己,增加一些内力。我不认为自己是个高手,更非大侠,然而因为我懂得少,只能自己重新来做,真恨自己没有在5年前多学习一些编程语言。

先来简单分析一下需求,就是一个字符串集合中,去掉重复的字符串,换句话说就是每一个字符串只保留一个。题目没有说是否保持原有的字符串输入顺序,作为完美主义的我,我还是将其当成了一个隐含的需求。那么下一步就是将问题进行简化和转化,如果我们能将这一堆字符串进行排序,那么最终遍历这个排过序的字符串集合,发现和前一个相同的字符串就跳过不输出,对于排序,再简单不过了,至少N中排序算法,本文不讨论各种排序算法,只使用最简单的冒泡排序来分析。那么怎么保留原有的输入序呢?这也很简单,就是在排序元素中增加一个指向原有序的指针即可,另外还有一种方法,那就是排序过程仅仅是一个删除重复元素的过程,而不影响原有的输入序列,这个动态行为可以用二叉树的插入来实现,或者其它的AVL树以及红黑树都可以,本文不会去谈这几棵树的特性,只是用最简单的排序二叉树来分析。

我们知道,在二叉树插入中,首先要进行一次查找,现在要做的是,如果没有找到相同的,则插入,如果找到了相同的,则不插入,同时为该元素置入删除标识。代码如下:

// // main.c // dup-del // // Created by ya zhao on 11-12-17. // Copyright 2011年 __MyCompanyName__. All rights reserved. // #include #include struct sorted_order_str_map_with_thread { char *sorted_order_str; //保存排序后的字符串 char *normal_order_str; //保存原始字符串 int tag; //指示是否要删除 struct sorted_order_str_map_with_thread *self; //指向原始的位置 }; void sort(struct sorted_order_str_map_with_thread smwt[], const int size, int (*cmp)(void *, void *), void (*swap)(void *q1, void *q2)); int cmp_node(void *, void *); //比较函数,如果相同则将其tag位设置为0,标示要删除 int cmp_node(void *q1, void *q2) { int res; struct sorted_order_str_map_with_thread *cmp1, *cmp2; cmp1 = (struct sorted_order_str_map_with_thread*)q1; cmp2 = (struct sorted_order_str_map_with_thread*)q2; res = strcmp(cmp1->sorted_order_str, cmp2->sorted_order_str); if (res == 0) { struct sorted_order_str_map_with_thread *p = cmp2->self; p->tag = 0; } return res; } //交换函数,不光要交换元素,还要交换其self指针 void swap_node(void *q1, void *q2) { struct sorted_order_str_map_with_thread *swp1, *swp2,*temp; char *strTemp; swp1 = (struct sorted_order_str_map_with_thread*)q1; swp2 = (struct sorted_order_str_map_with_thread*)q2; strTemp = swp1->sorted_order_str; temp = (swp1->self); swp1->sorted_order_str = swp2->sorted_order_str; swp1->self = swp2->self; swp2->sorted_order_str = strTemp; swp2->self = temp; } //标准冒泡排序 void sort(struct sorted_order_str_map_with_thread smwt[], const int size, int (*cmp)(void *q1, void *q2), void (*swap)(void *q1, void *q2)) { int flag = 1; for (int i = 0; i < size - 1; i ++) { flag = 1; for (int j = 0; j < size - i - 1; j ++) { int res = 0; if ((res = cmp(&smwt[j], &smwt[j+1])) > 0) { swap(&smwt[j], &smwt[j+1]); flag = 0; } } if (flag == 1) break; } } int main (int argc, const char * argv[]) { int i = 0; //为了简化,下面使用了最恶心的初始化方法。方便复制粘贴 struct sorted_order_str_map_with_thread smwt[20] = {{NULL, NULL, 0 NULL}}; smwt[0].sorted_order_str =smwt[0].normal_order_str = "323"; smwt[0].self = &smwt[0]; smwt[0].tag = 1; smwt[1].sorted_order_str = smwt[1].normal_order_str="223"; smwt[1].self = &smwt[1]; smwt[1].tag = 2; smwt[2].sorted_order_str =smwt[2].normal_order_str= "723"; smwt[2].self = &smwt[2]; smwt[2].tag = 3; smwt[3].sorted_order_str =smwt[3].normal_order_str= "823"; smwt[3].self = &smwt[3]; smwt[3].tag = 4; smwt[4].sorted_order_str =smwt[4].normal_order_str= "123"; smwt[4].self = &smwt[4]; smwt[4].tag = 5; smwt[5].sorted_order_str =smwt[5].normal_order_str= "423"; smwt[5].self = &smwt[5]; smwt[5].tag = 6; smwt[6].sorted_order_str =smwt[6].normal_order_str= "123"; smwt[6].self = &smwt[6]; smwt[6].tag = 7; smwt[7].sorted_order_str =smwt[7].normal_order_str= "723"; smwt[7].self = &smwt[7]; smwt[7].tag = 8; smwt[8].sorted_order_str = smwt[8].normal_order_str="523"; smwt[8].self = &smwt[8]; smwt[8].tag = 9; smwt[9].sorted_order_str =smwt[9].normal_order_str= "823"; smwt[9].self = &smwt[9]; smwt[9].tag = 10; sort(smwt, 10, cmp_node, swap_node); //下面使用了最恶心的输出,经典### for (i = 0; i< 10; i++) { printf("###:%s tag:%d\n", smwt[i].normal_order_str, smwt[i].tag); } for (i = 0; i< 10; i++) { printf("@@@:%s tag:%d\n", smwt[i].sorted_order_str, smwt[i].tag); } for (i = 0; i< 10; i++) { if (smwt[i].tag != 0){ printf("@@@&&:%s\n", smwt[i].normal_order_str); } } return 0; }

下面的一种方法使用了标准的二叉树插入,注意,插入仅仅是为了删除重复元素,实际上,各种语言各种库的标准Map实现很多也是使用了树,比如java.util中的TreeMap就是使用了红黑树。下面直接给出代码,基于排序二叉树的代码:

// // main.c // test-xcode // // Created by ya zhao on 11-12-17. // Copyright 2011年 __MyCompanyName__. All rights reserved. // #include #include #include struct string_node { char *string; int tag; //标示是否被删除 }; //标准排序二叉树 struct string_tree { struct string_node *strn; struct string_tree* left,*right; }; struct string_tree *add_node(struct string_tree *, struct string_node *str, int (*cmp)(struct string_node *, struct string_node *)); int normalcmp(struct string_node *, struct string_node *); //简单的字符串比较 int normalcmp(struct string_node *n1, struct string_node *n2) { return strcmp (n1->string,n2->string); } int main(int argc, char **argv) { int j = 0; for (j = 0; j < 1; j++) { struct string_tree *root; struct string_node str[9] = {{"123",1},{"456",1},{"234",1},{"123",1},{"347",1},{"129",1},{"888",1}, {"568",1}, {"456",1}}; root = NULL; int i = 0; while (i<9) { root = add_node(root, &str[i], normalcmp); i ++; } i=0; while (i<9){ if (str[i].tag) { printf("&&&:%s\n", str[i].string); } i++; } } return 0; } struct string_tree *add_node(struct string_tree *p, struct string_node *new, int (*cmp)(struct string_node *n1, struct string_node *n2)) { int cmp_ret; if (p == NULL) { p = (struct string_tree *)calloc(1, sizeof(struct string_tree)); p->strn = (struct string_node*)calloc(1, sizeof(struct string_node)); memcpy(p->strn, new, sizeof(struct string_node)); p->left = p->right = NULL; } else if ((cmp_ret = cmp(new, p->strn)) == 0) { new->tag =0; } else if (cmp_ret < 0) { p->left = add_node(p->left, new, cmp); } else { p->right = add_node(p->right, new, cmp); } return p; }

经过测试,自己实现的上述算法效率还可以,当然这里不该去比较效率,留下个思路即可,在没有库可用的情况下,也可以自己实现它。在现实中,特别是在软件工程中,还是使用现成的map比较好。

c语言集合除去相同元素,使用C语言去掉字符串集合重复元素相关推荐

  1. 《 Python List列表全实例详解系列(四)》__列表删除元素(4种方法)删除重复元素(去重)(8种方法)

    <  Python List列表全实例详解系列(四)> __列表删除元素(4种方法)删除重复元素(去重)(8种方法) 我的技术成长&学习资料整理分享之路 我遇到问题查找资料时,经常 ...

  2. python重复元素判定去除_Python去除列表中重复元素的方法

    这篇文章主要介绍了Python去除列表中重复元素的方法,实例分析了Python中去除列表重复元素的使用技巧,需要的朋友可以参考下 本文实例讲述了Python去除列表中重复元素的方法.分享给大家供大家参 ...

  3. C++快速实现去掉数组中重复元素

    c++数组去重基础知识 #include<iostream> #include<vector> #include<algorithm> #include<fu ...

  4. java去重复元素并打印_Java打印数组中重复元素

    Java打印数组中重复元素 1 说明 在此程序中,我们需要打印数组中存在的重复元素.这可以通过两个循环来完成.第一个循环将选择一个元素,第二个循环将通过将所选元素与其他元素进行比较来遍历整个数组.如果 ...

  5. python去重复元素_python 去除单个list中的重复元素

    原博文 2020-02-23 08:31 − python中使用set 的方法,去除单个list中重复的元素并且保持元素的先后顺序不变. ``` list1 = ['a','a','b','c','d ...

  6. python 如何获取列表(List)中指定元素的下标? index() enumerate() 获取重复元素下标

    获取列表中指定元素下标 方法1 a = [72, 55, 77, 96, 2, 77] print(a.index(77)) # 2 注意:当列表中包含多个相同的元素时,index()函数返回的是第一 ...

  7. 编写一个方法,去掉数组中重复元素

    方法一:排序后相邻去除法 arr = [1, 2, 5, 1, 3, 7, 9, 5];function unique(arr) {arr.sort();var _arr = [arr[0]];//结 ...

  8. C语言-顺序表直接删除重复元素

    今天想把之前的合并后的单链表中重复的元素删去,结果在一个函数中,竟然不可以直接调用delete函数,似乎是传值出现的问题,已经在主函数中将LC传值到delete_repeatnum,在delete_r ...

  9. 力扣题目——217. 存在重复元素

    注:本文的实现思路主要是基于JS(JavaScript),涉及到的一些函数都是JS中的自带函数 题目描述 给定一个整数数组,判断是否存在重复元素. 如果存在一值在数组中出现至少两次,函数返回 true ...

最新文章

  1. as3自定义加载图片类
  2. 关于CVPR 2019投稿的一些感想
  3. 2020-08-20如何获取AWS的Access Key ID 和 Secret Access Key (Unable to find credentials)
  4. Objective C 链式调用
  5. hdu 1228-A+B
  6. 经纬度画轨迹图_实战Python制作炫酷的个人3D动态足迹图
  7. 启动django服务器报错raise errorclass(errno, errval) django.db.utils.InternalError
  8. php 查找数组相同元素,查找数组中重复的元素
  9. iOS项目的完整重命名方法图文教程
  10. 【转】Maven实战(八)---模块划分
  11. Linux的shell编程(三)
  12. 【kafka】Kafka JMX监控报错 Failed to get broker metrics for BrokerIdentity
  13. 分布式文件系统-HDFS(   HDFS全称是Hadoop Distributed System)
  14. SecureCRT使用过程中 光标会丢失的问题
  15. DHTML Scriptlets 容器对象参考手册
  16. python键盘输入字典类型_python数据类型——字典类型
  17. 重症监护室(ICU)100260
  18. python 读取txt文件并在txt每行文件后面增加内容
  19. 声学模型(语音识别中的)--学习笔记
  20. vue打测试包和正式包的配置

热门文章

  1. 浅谈Aho-Corasick automaton(AC自动机)
  2. Flask 中内置的 Session
  3. 【01】《正则表达式必知必会》(已看)(仅存放)
  4. 用HttpURLConnection发送http请求
  5. [Flexbox] Using order to rearrange flexbox children
  6. vue --- 全局注册子组件,并导入全局的子组件
  7. Laravel 中的环境与配置
  8. DOM-6 【兼容】读写样式属性、操作伪元素、运动元素初探
  9. js基础总结性能优化
  10. 对于多属性类型系统的数据库设计