打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
算法11(给一个很长的字符串str 还有一个字符集比如{a,b,c} 找出str 里包含{a,b,c}的最短子串。要求O(n).)

http://blog.csdn.net/yuucyf/article/details/6714235

题目:

给一个很长的字符串str 还有一个字符集比如{a,b,c} 找出str 里包含{a,b,c}的最短子串。要求O(n).

比如,字符集是a,b,c,字符串是abdcaabcx,则最短子串为abc。

思路一:

用两个变量Front, Rear 指向这个字串(str)区间的头和尾,开始的时候同指向字符串首地址,用一个变量int achSubCnt[256]={0}记录字符集a,b,c 个数,用另外一个变量int achCnt[256] = {0}记录当前这个子串里a,b,c各自出现的个数,一个变量i32CurSum记录当前Front,Rear指向的区间中有多少个字符集里面的元素了,Rear 一直加,然后判断Rear所指的字符是否是在字符集中,如果是那么更新achCnt[]和i32CurSum的值,直到i32CurSum等于字符集个数,然后Front++,直到achCnt[]里某个字符个数为0,这样就找到一个符合条件的字串了。
继续前面的操作,就可以找到最短的了。(如果题目要求把所有匹配字符集中的字符串罗列出来也是可以的,这样还可以不进行匹配字串长度的比较)

代码如下:

  1. /*--------------------------------
  2. Copyright by yuucyf. 2011.08.24
  3. ---------------------------------*/
  4. #include "stdafx.h"
  5. #include <iostream>
  6. using namespace std;
  7. #define CHAR_COUNT 256
  8. typedef struct tagPosition
  9. {
  10. int i32Front;
  11. int i32Rear;
  12. tagPosition()
  13. {
  14. i32Front = i32Rear = 0;
  15. }
  16. }S_StrPos;
  17. bool FindShortSubString(const char* pszStr, const char *pszSubStr, S_StrPos &sShortSubStr)
  18. {
  19. if (NULL == pszStr || NULL == pszSubStr)
  20. return false;
  21. int i32Len = _tcslen(pszStr);
  22. int i32SubLen = _tcslen(pszSubStr);
  23. if (i32Len <= 0 || i32SubLen <= 0)
  24. return false;
  25. sShortSubStr.i32Front = sShortSubStr.i32Rear = 0;
  26. int i32CurSum = 0;
  27. int achSubCnt[CHAR_COUNT] = {0};
  28. int achCnt[CHAR_COUNT] = {0};
  29. int i32I = 0;
  30. for (i32I = 0; i32I < i32SubLen; i32I++)
  31. {
  32. achSubCnt[pszSubStr[i32I]]++;
  33. }
  34. int Front = 0, Rear = 0;
  35. while (Front < i32Len && Rear < i32Len)
  36. {
  37. if (i32CurSum != i32SubLen)
  38. {
  39. if (achSubCnt[pszStr[Rear]] > 0)
  40. {
  41. achCnt[pszStr[Rear]]++;
  42. if (achSubCnt[pszStr[Rear]] >= achCnt[pszStr[Rear]])
  43. i32CurSum++;
  44. }
  45. Rear++;
  46. }
  47. else
  48. {
  49. achCnt[pszStr[Front]]--;
  50. if (achCnt[pszStr[Front]] == 0) //Find a sub string.
  51. {
  52. if (sShortSubStr.i32Rear == 0)
  53. {
  54. sShortSubStr.i32Front = Front;
  55. sShortSubStr.i32Rear = Rear;
  56. }
  57. else if ((sShortSubStr.i32Rear - sShortSubStr.i32Front) > (Rear - Front))
  58. {
  59. sShortSubStr.i32Front = Front;
  60. sShortSubStr.i32Rear = Rear;
  61. }
  62. i32CurSum--;
  63. }
  64. Front++;
  65. }
  66. }
  67. //可能是Rear已经到达字符串尾,可是还存在i32CurSum == i32SubLen的情况,
  68. //所以要从Front开始往前遍历,找到最后一个满足条件的字串。
  69. while (i32CurSum == i32SubLen)
  70. {
  71. achCnt[pszStr[Front]]--;
  72. if (achCnt[pszStr[Front]] == 0) //Find a sub string.
  73. {
  74. if (sShortSubStr.i32Rear == 0)
  75. {
  76. sShortSubStr.i32Front = Front;
  77. sShortSubStr.i32Rear = Rear;
  78. }
  79. else if ((sShortSubStr.i32Rear - sShortSubStr.i32Front) > (Rear - Front))
  80. {
  81. sShortSubStr.i32Front = Front;
  82. sShortSubStr.i32Rear = Rear;
  83. }
  84. i32CurSum--;
  85. }
  86. Front++;
  87. }
  88. return (sShortSubStr.i32Rear != 0);
  89. }
  90. int _tmain(int argc, _TCHAR* argv[])
  91. {
  92. char aszStr[] = "abdcaabcx";
  93. char aszSubStr[] = "abc";
  94. S_StrPos sStrPos;
  95. if (FindShortSubString(aszStr, aszSubStr, sStrPos))
  96. {
  97. cout << "最短的字串为:";
  98. for (int i32I = sStrPos.i32Front; i32I < sStrPos.i32Rear; i32I++)
  99. cout << aszStr[i32I];
  100. cout << endl;
  101. }
  102. return 0;
  103. }
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
C语言按层次遍历二叉树算法
队列
打开音量控制面 板上面的英文字是什么意思?
瑞士BUCHER DURO 6X6
计算队列中的元素个数
汽车配件英语
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服