给定一个任意的 char[]
找出字符串中字符对的数量。所以这将是 3:
aabbcc
如果相邻的两对相同字符都应计算在内。所以这将是 3:
aaaabb
中断的单个 char
必须重置连续字符对的计数。所以这将是 1:
aabcc
如果中断的单个字符与前面的字符对相同,它不会重置连续字符对的计数。所以这将是 3:
aabbbccc
这是对 this question 的改编.该问题的原始解释很有趣,但评论不断改变该问题的原始解释的性质。 This was my answer原来的解释,我想知道是否可以对其进行改进?
最佳答案
循环控制应该使用数组的大小作为范围,如果 i
是到的索引,则 a[i + 1]
的索引可能越界最后一个元素,因此使用 a[i - 1]
代替并迭代范围 [1
.. sizeof(a)/sizeof(a[0] )
] 更可取
该算法最好用 3 个变量求解:
char* last
指向当前字符串连续字符的第一个元素int count1
当前count中连续对的个数int count
记录的最大连续对数
该算法最好用状态机来说明。它将运行于:
- 在输入时将
last
设置为NULL
,如果count1
大于count
,则分配count1
到count
,并将count1
重置为0
- 输入时将
last
设置为该连续字符串中的第一个字符 (a[i-1]
) - 输入时加上 last 指向的连续字符数除以 2,以便只找到对
这是带有内联注释的更正代码:
size_t i = 0;
char* last = NULL;
long int count1 = 0;
long int count = 0;
char a[] = {'d', 'p', 'p', 'c', 'c', 'd', 'd', 'd'};
while (++i < sizeof(a) / sizeof(a[0])) { // This will iterate over the range: [1 .. sizeof(a) / sizeof(a[0])]
if (a[i - 1] == a[i]) { // Test previous character to avoid going out of range
if (last == NULL) { // Entry to state 2
last = a + i - 1;
}
} else if (last != NULL) {
if (a + i - last > 1) { // Entry to state 3
count1 += (a + i - last) / 2;
last = a + i;
} else { // Entry to state 1
if (count1 > count) { // If the current count is larger
count = count1; // Replace the maximum count
}
count1 = 0; // Reset the current count
last = NULL;
}
}
}
if (last != NULL) { // Entry to state 3
if (a + (sizeof(a) / sizeof(a[0])) - last > 1) {
count1 += (a + (sizeof(a) / sizeof(a[0])) - last) / 2;
}
if (count1 > count) { // If the current count is larger
count = count1; // Replace the maximum count
}
}
printf("%ld", count);
[ Live Example ]
关于c - 查找列表中重复的对数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32715322/