假设两个字符串的长度相等,是否可以使用C来了解它们共有多少个字符? 例如,如果我们输入FABBOL和LABTIF,程序应输出4.如果我们输入FABBOL和LABBIF,程序应输出5.
答案 0 :(得分:1)
计算每个角色并进行检查。 像这样:
#include <stdio.h>
#include <string.h>
unsigned number_of_common(const char *s1, const char *s2){
unsigned count[256] = {0};
//Make it unsigned for use as subscript.
const unsigned char *s = (const unsigned char*)s1;
while(*s)
++count[*s++];
unsigned common = 0;
for(s = (const unsigned char*)s2; *s; ++s){
if(count[*s]){
++common;
--count[*s];
}
}
return common;
}
int main(void){
unsigned count[256];
char string1[256], string2[256];
printf("input string #1>");fflush(stdout);
fgets(string1, sizeof string1, stdin);
string1[strcspn(string1, "\n")] = 0;//chomp newline
printf("input string #2>");fflush(stdout);
fgets(string2, sizeof string2, stdin);
string2[strcspn(string2, "\n")] = 0;
printf("number of common character is %u\n", number_of_common(string1, string2));
return 0;
}
答案 1 :(得分:1)
有很多方法。这是三个:
当被要求手工计算字符时,一种方法是模仿许多人(在他们的头上或纸上)做的事情。我们调用字符串s1
和s2
。无论哪个都无关紧要,无论如何都会得到相同的结果。
Set Count = 0
For each character c in s1:
If s2 contains c:
Strike out the character in s2
Set Count = Count + 1
End for
Return Count
请注意,s2
之上的其中一个字符串已被修改 - 以避免在s2
中多次出现同一字符(如果它在s1
中出现多次)。这通常意味着您使用s2
的临时副本,因此原始s2
不会被破坏(并且可以是例如字符串文字;它们不能被修改)。 C有一个函数strchr()
,可用于定位字符串是否包含特定字符;如果宽字符串包含特定的宽字符,则为函数wcschr()
。
算法方面,这具有 O(NM)时间复杂度,以及 O(N)空间复杂度,其中 N 和 M 是两个字符串的长度。
对于普通(窄)字符串,另一种方法是创建两个字符计数数组 - 即带有CHAR_MAX - CHAR_MIN + 1
元素的无符号整数数组 - 并计算每个字符的出现次数。结果是所有字符的总和,使用每个字符的较小计数。
如果字符串长度为 N 且 M ,并且有 L 可能的字符,则此方法具有 O(max( N,M,L))时间复杂度,以及 O(L)空间复杂度。
您可以对每个字符串中的字符进行排序。订单本身并不重要,只要两者都相同。
从每个排序字符串中的第一个字符开始,并在每个排序字符串中的一个字符上保留一个索引(一个手指!)。从计数零开始,然后:
如果一个字符在另一个字符之前,则跳过前一个字符,将该索引(手指)移动到下一个字符。
如果一个或两个索引(手指)到达各自字符串的末尾,我们就完成了;返回计数。
如果两个排序字符串中的索引指向相似的字符,则增加计数,并推进两个索引(手指)
这的时间复杂度为 O(max(N log N,M log M)),因为排序通常是通过比较排序完成的,并且最多只有时间复杂度 O(N log N)。如果你不想使原始字符串混乱,你可能需要 O(N + M)额外的空间。
可以使用基数排序来获得 O(max(N,M))时间复杂度(因为存在严格有限数量的唯一字符,并且基数排序不是比较基于排序),但除非字符串非常长,否则它将比实际中许多基于比较的排序慢。此外,基数排序通常需要相当多的额外空间(具体取决于实现的多少)。
这非常类似于删除已经考虑的字符,除了我们首先对字符重新排序,并通过移动相应的索引(手指)来“敲击”它们。
答案 2 :(得分:-1)
对字符串中的字符进行排序。然后......
Sudocode(这些日子对我来说c是一种只读语言):
int str1Idx = 0;
int str2Idx = 0;
int hitCount = 0;
while ( str1Idx < strlen( string1 ) )
{
while ( str2Idx < strlen( string2 ) )
{
if ( string1[ str1Idx ] == string2[ str2Idx ] )
{
++hitCount;
++str2Idx;
break;
}
if ( string1[ str1Idx ] < string2[ str2Idx ] )
{
break;
}
++str2Idx;
}
++str1Idx;
}
显然,我正在简化事情,因为这是c和排序甚至字符比较等事情比更现代的语言更多的工作,但这是它的要点。
你走在正确的轨道上;首先对字符进行排序,其余部分应该落实到位。