2.判断回文(Anagrams)
Question:Write a method to decide if two strings are anagrams or not.(写一个函数判断两个字符串是否使用相同的字符构成。)
简单方法:对两个字符串重排序,再比较是否相等。(Java,C#等内置字符操作方法的容易实现!)
看这道题时首先就犯了一个致命的错误,把单词anagrams意思理解错了。以为题目是判断两个字符串是否互为反转(查看有道的答案,那也太简单了吧)。最后google,发现原来是回文的意思。英语不好害死人啊。
之后设计算法时,方法都比较土,时间复杂度O(n^2)。没办法最后还是看作者的答案了。开始还没看懂,囧。最后发现真是精妙,复杂度为O(n)。以下为代码:
View Code
int findAnagrams(char * str1, char *str2) { int arr[256]; int i; int uniqueSum = 0; int completSum = 0; for(i = 0; i < 256; i++) { arr[i] = 0; } if(strlen(str1) != strlen(str2)) /* 长度不等肯定不是同构的 */ return 1; for( i = 0; i < strlen(str1); i++) { if(arr[*(str1+i)] == 0) { ++uniqueSum; /* 统计不同字符总数 */ } ++arr[*(str1+i)]; /* 统计相同字符出现的次数 */ } for( i = 0; i < strlen(str2); i++) { if(arr[*(str2+i) == 0]) { return 1; /* str2中有字符没有在arr数组中出现,说明不是同构 */ } else { arr[*(str2+i)]--; } if(arr[*(str2+i)] == 0) { ++completSum; if(completSum == uniqueSum) { return 0; } } } return 1; }
看代码可知,本题核心思路就是数组arr[256],通过两个字符串共同“操作”一个一维数组,从而达到判断的目的。另外一个还是用字符的ASSIC配合使用。
举个例子 str1 = “hello”,hello中各字符对应ASSIC值分别为:104,101,108,111。
for( i = 0; i < strlen(str1); i++) { if(arr[*(str1+i)] == 0) { ++uniqueSum; /* 统计不同字符总数 */ } ++arr[*(str1+i)]; /* 统计相同字符出现的次数 */ }
上述循环运算之后数组的值将会改变:
arr[104] = 1;
arr[101] = 1;
arr[108] = 2;
arr[111] = 1;
uniqueSum = 4;
如果str2 = "holel",在下段循环中就会将之前的数组值重新赋值,即变回0.
for( i = 0; i < strlen(str2); i++) { if(arr[*(str2+i) == 0]) { return 1; /* str2中有字符没有在arr数组中出现,说明不是同构 */ } else { arr[*(str2+i)]--; }
}
以下代码就是统计str2中单个字符个数,最后与str1的统计结果比较,也是核心部分:
if(arr[*(str2+i)] == 0) { ++completSum; if(completSum == uniqueSum) { return 0; } }
数据库不平,何以平天下,啊啊啊~
posted on 2012-07-10 22:55 hackergodness 阅读(1043) 评论(0) 编辑 收藏 举报