关于位图的一道典型问题

问题:
假设两个字符串中所含有的字符和个数都相同我们就叫这两个字符串匹配,比如:abcda和adabc,由于出现的字符个数都是相同,只是顺序不同,所以这两个字符串是匹配的。算法要求高效,现在需要你来实现下面的函数:
bool Is_Match(char *str1,char *str2)

【位图方法】
算法思路:用空间换取时间。
第1步:首先判断两个字符串的长度是否相同。
第2步:如果长度相同,遍历两个字符串,使用位图统计每个字符出现的次数。
第3步:比较两个位图,看两个字符串中每个字符出现的次数是否相等。
算法整体时间复杂度和空间复杂度都为O(n)。

#include <cstdio> #include <cstdlib> #include <cstring> #include <cassert> bool Is_Match(char *str1, char *str2) { const size_t LEN=256; int str1_map[LEN]={0}; int str2_map[LEN]={0}; char *str1_tmp=str1; assert(str1 != NULL && str2 != NULL); // check first if (strlen(str1) != strlen(str2)) return false; // mark data in map while (*str1) { str1_map[*str1]++; ++str1; } while (*str2) { str2_map[*str2]++; ++str2; } // compare map while (*str1_tmp) { if (str1_map[*str1_tmp] != str2_map[*str1_tmp]) return false; ++str1_tmp; } // inefficient way /* for (int i=0; i!=LEN; ++i) { if (str1_map[i] != str2_map[i]) return false; } */ return true; } int main() { char str1[128]={0}; char str2[128]={0}; scanf("%s%s",str1,str2); if (Is_Match(str1,str2)) { printf("matched string/n"); } else { printf("non-matched string/n"); } system("pause"); return 0; }

 

等价的方法:

bool Is_Mach(char *str1, char *str2) { bool isMach = (strlen(str1) == strlen(str2)); if (isMach) { int count[256] = {1}; for(char *p = str1; *p; ++count[*p++]) ; for(char *p = str2; *p; ++p) { if(--count[*p] == 0) { isMach = false; break; } } } return isMach; } bool Is_Match(char *str1, char *str2) { unsigned int isMach = strlen(str1) - strlen(str2); if (isMach == 0) { unsigned int count[256] = {0}; for(char *p = str1; *p; ++count[*p++]) ; for(char *p = str2; *p; isMach |= --count[*p++]) ; isMach >>= sizeof(unsigned int) * 8 - 1; } return isMach == 0; }


【排序方法】
算法思路:
第一步:首先判断两个字符串的长度是否相同。
第二步:如果相同,再对两个字符串进行排序。
第三步:对排序后的字符串进行比较。
算法最好时间复杂度为O(nlogn)。
#include <cstdio> #include <cstdlib> #include <cassert> #include <string> #include <algorithm> using std::string; bool Is_Match(char *str1, char *str2) { assert(str1 != NULL && str2 != NULL); string s1(str1), s2(str2); bool bRes=(s1.length() == s2.length()); if (bRes) { sort(s1.begin(), s1.end()); sort(s2.begin(),s2.end()); bRes=(s1 == s2); } return bRes; } int main() { char str1[128]={0}; char str2[128]={0}; scanf("%s%s",str1,str2); if (Is_Match(str1,str2)) { printf("matched string/n"); } else { printf("non-matched string/n"); } system("pause"); return 0; } 

 

【哈希表方法】
算法思路:注意哈希的力度。

bool Is_Match(char *str1, char *str2) { int num = 0; unsigned int all = 0; unsigned int tmp = 0; while(*str1) { all+=(((*str1) * (*str1))*256); str1++; num++; } tmp = all; while(*str2) { all+=(((*str2) * (*str2))*256); str2++; num--; } if (tmp*2 == all && num == 0) return true; else return false; }

 

更多可见:http://topic.csdn.net/u/20110110/17/dcdb6234-842b-48be-a286-6ffb5b2534f4.html?518

 

 

你可能感兴趣的:(算法,String,null,System)