歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 使用C語言去掉字符串集合重復元素

使用C語言去掉字符串集合重復元素

日期:2017/3/1 10:44:48   编辑:Linux編程

有一種最直接的方法可以去掉一個集合中重復的元素,這種方法據說就是“交給下面去做”,然而有時候,你自己動手去做一下也是不錯的。如果交給下面去做,最直接的選擇就是使用map,在java中,我們有HashMap,TreeMap等等實現了map接口的類可用,c++中,同樣有STL的同類集合可以使用,在各類高級語言中,就更不必說了,然而在c中,就沒有那麼幸運了,很多東西需要你來自己實現。

根據《C語言內力修煉與軟件工程》見 http://www.linuxidc.com/Linux/2011-12/50393p3.htm ,用c語言自行實現這個東西,其實對於軟件工程而言沒有必要,然而可以訓練一下自己,增加一些內力。我不認為自己是個高手,更非大俠,然而因為我懂得少,只能自己重新來做,真恨自己沒有在5年前多學習一些編程語言。

先來簡單分析一下需求,就是一個字符串集合中,去掉重復的字符串,換句話說就是每一個字符串只保留一個。題目沒有說是否保持原有的字符串輸入順序,作為完美主義的我,我還是將其當成了一個隱含的需求。那麼下一步就是將問題進行簡化和轉化,如果我們能將這一堆字符串進行排序,那麼最終遍歷這個排過序的字符串集合,發現和前一個相同的字符串就跳過不輸出,對於排序,再簡單不過了,至少N中排序算法,本文不討論各種排序算法,只使用最簡單的冒泡排序來分析。那麼怎麼保留原有的輸入序呢?這也很簡單,就是在排序元素中增加一個指向原有序的指針即可,另外還有一種方法,那就是排序過程僅僅是一個刪除重復元素的過程,而不影響原有的輸入序列,這個動態行為可以用二叉樹的插入來實現,或者其它的AVL樹以及紅黑樹都可以,本文不會去談這幾棵樹的特性,只是用最簡單的排序二叉樹來分析。

我們知道,在二叉樹插入中,首先要進行一次查找,現在要做的是,如果沒有找到相同的,則插入,如果找到了相同的,則不插入,同時為該元素置入刪除標識。代碼如下:

  1. //
  2. // main.c
  3. // dup-del
  4. //
  5. // Created by ya zhao on 11-12-17.
  6. // Copyright 2011年 __MyCompanyName__. All rights reserved.
  7. //
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. struct sorted_order_str_map_with_thread {
  11. char *sorted_order_str; //保存排序後的字符串
  12. char *normal_order_str; //保存原始字符串
  13. int tag; //指示是否要刪除
  14. struct sorted_order_str_map_with_thread *self; //指向原始的位置
  15. };
  16. void sort(struct sorted_order_str_map_with_thread smwt[], const int size,
  17. int (*cmp)(void *, void *),
  18. void (*swap)(void *q1, void *q2));
  19. int cmp_node(void *, void *);
  20. //比較函數,如果相同則將其tag位設置為0,標示要刪除
  21. int cmp_node(void *q1, void *q2)
  22. {
  23. int res;
  24. struct sorted_order_str_map_with_thread *cmp1, *cmp2;
  25. cmp1 = (struct sorted_order_str_map_with_thread*)q1;
  26. cmp2 = (struct sorted_order_str_map_with_thread*)q2;
  27. res = strcmp(cmp1->sorted_order_str, cmp2->sorted_order_str);
  28. if (res == 0) {
  29. struct sorted_order_str_map_with_thread *p = cmp2->self;
  30. p->tag = 0;
  31. }
  32. return res;
  33. }
  34. //交換函數,不光要交換元素,還要交換其self指針
  35. void swap_node(void *q1, void *q2)
  36. {
  37. struct sorted_order_str_map_with_thread *swp1, *swp2,*temp;
  38. char *strTemp;
  39. swp1 = (struct sorted_order_str_map_with_thread*)q1;
  40. swp2 = (struct sorted_order_str_map_with_thread*)q2;
  41. strTemp = swp1->sorted_order_str;
  42. temp = (swp1->self);
  43. swp1->sorted_order_str = swp2->sorted_order_str;
  44. swp1->self = swp2->self;
  45. swp2->sorted_order_str = strTemp;
  46. swp2->self = temp;
  47. }
  48. //標准冒泡排序
  49. void sort(struct sorted_order_str_map_with_thread smwt[], const int size,
  50. int (*cmp)(void *q1, void *q2),
  51. void (*swap)(void *q1, void *q2))
  52. {
  53. int flag = 1;
  54. for (int i = 0; i < size - 1; i ++) {
  55. flag = 1;
  56. for (int j = 0; j < size - i - 1; j ++) {
  57. int res = 0;
  58. if ((res = cmp(&smwt[j], &smwt[j+1])) > 0) {
  59. swap(&smwt[j], &smwt[j+1]);
  60. flag = 0;
  61. }
  62. }
  63. if (flag == 1)
  64. break;
  65. }
  66. }
  67. int main (int argc, const char * argv[])
  68. {
  69. int i = 0;
  70. //為了簡化,下面使用了最惡心的初始化方法。方便復制粘貼
  71. struct sorted_order_str_map_with_thread smwt[20] = {{NULL, NULL, 0 NULL}};
  72. smwt[0].sorted_order_str =smwt[0].normal_order_str = "323";
  73. smwt[0].self = &smwt[0];
  74. smwt[0].tag = 1;
  75. smwt[1].sorted_order_str = smwt[1].normal_order_str="223";
  76. smwt[1].self = &smwt[1];
  77. smwt[1].tag = 2;
  78. smwt[2].sorted_order_str =smwt[2].normal_order_str= "723";
  79. smwt[2].self = &smwt[2];
  80. smwt[2].tag = 3;
  81. smwt[3].sorted_order_str =smwt[3].normal_order_str= "823";
  82. smwt[3].self = &smwt[3];
  83. smwt[3].tag = 4;
  84. smwt[4].sorted_order_str =smwt[4].normal_order_str= "123";
  85. smwt[4].self = &smwt[4];
  86. smwt[4].tag = 5;
  87. smwt[5].sorted_order_str =smwt[5].normal_order_str= "423";
  88. smwt[5].self = &smwt[5];
  89. smwt[5].tag = 6;
  90. smwt[6].sorted_order_str =smwt[6].normal_order_str= "123";
  91. smwt[6].self = &smwt[6];
  92. smwt[6].tag = 7;
  93. smwt[7].sorted_order_str =smwt[7].normal_order_str= "723";
  94. smwt[7].self = &smwt[7];
  95. smwt[7].tag = 8;
  96. smwt[8].sorted_order_str = smwt[8].normal_order_str="523";
  97. smwt[8].self = &smwt[8];
  98. smwt[8].tag = 9;
  99. smwt[9].sorted_order_str =smwt[9].normal_order_str= "823";
  100. smwt[9].self = &smwt[9];
  101. smwt[9].tag = 10;
  102. sort(smwt, 10, cmp_node, swap_node);
  103. //下面使用了最惡心的輸出,經典###
  104. for (i = 0; i< 10; i++) {
  105. printf("###:%s tag:%d\n", smwt[i].normal_order_str, smwt[i].tag);
  106. }
  107. for (i = 0; i< 10; i++) {
  108. printf("@@@:%s tag:%d\n", smwt[i].sorted_order_str, smwt[i].tag);
  109. }
  110. for (i = 0; i< 10; i++) {
  111. if (smwt[i].tag != 0){
  112. printf("@@@&&:%s\n", smwt[i].normal_order_str);
  113. }
  114. }
  115. return 0;
  116. }
Copyright © Linux教程網 All Rights Reserved