我没有任何评论就遇到了这个功能。我想知道这个功能在做什么?有什么帮助吗?
int flr(int n, char a[])
{
#define A(i) a[((i) + k) % n]
int l[n], ls = n, z[n], min = 0;
for (int i = 0; i < n; i++)
{
l[i] = i;
z[i] = 1;
}
for (int k = 0; ls >= 2; k++)
{
min = l[0];
for (int i=0; i<ls; i++) min = A(l[i])<A(min) ? l[i] : min;
for (int i=0; i<ls; i++) z[A(l[i])!=A(min) ? l[i] : (l[i]+k+1)%n] = 0;
for (int ls_=ls, i=ls=0; i<ls_; i++) if (z[l[i]]) l[ls++] = l[i];
}
return ls == 1 ? l[0] : min;
}
答案 0 :(得分:8)
多么有趣的问题!
其他海报是正确的,它返回最小的索引,但它实际上比那更有趣。
如果你将数组视为循环(即当你越过末尾,回到开头),函数返回最小词典子序列的起始索引。
如果只有一个元素是最小的,则返回该元素。如果多个元素是最小的,我们将比较每个最小元素的下一个元素。
E.g。输入为10
和{0, 1, 2, 1, 1, 1, 0, 0, 1, 0}
:
重构和评论的代码如下:
int findStartOfMinimumSubsequence(int length, char circular_array[])
{
#define AccessWithOffset(index) circular_array[(index + offset) % length]
int indicesStillConsidered[length], count_left = length, indicator[length], minIndex = 0;
for (int index = 0; index < length; index++)
{
indicesStillConsidered[index] = index;
indicator[index] = 1;
}
// Keep increasing the offset between pairs of minima, until we have eliminated all of
// them or only have one left.
for (int offset = 0; count_left >= 2; offset++)
{
// Find the index of the minimal value for the next term in the sequence,
// starting at each of the starting indicesStillConsidered
minIndex = indicesStillConsidered[0];
for (int i=0; i<count_left; i++)
minIndex = AccessWithOffset(indicesStillConsidered[i])<AccessWithOffset(minIndex) ?
indicesStillConsidered[i] :
minIndex;
// Ensure that indicator is 0 for indices that have a non-minimal next in sequence
// For minimal indicesStillConsidered[i], we make indicator 0 1+offset away from the index.
// This prevents a subsequence of the current sequence being considered, which is just an efficiency saving.
for (int i=0; i<count_left; i++){
offsetIndexToSet = AccessWithOffset(indicesStillConsidered[i])!=AccessWithOffset(minIndex) ?
indicesStillConsidered[i] :
(indicesStillConsidered[i]+offset+1)%length;
indicator[offsetIndexToSet] = 0;
}
// Copy the indices where indicator is true down to the start of the l array.
// Indicator being true means the index is a minimum and hasn't yet been eliminated.
for (int count_before=count_left, i=count_left=0; i<count_before; i++)
if (indicator[indicesStillConsidered[i]])
indicesStillConsidered[count_left++] = indicesStillConsidered[i];
}
return count_left == 1 ? indicesStillConsidered[0] : minIndex;
}
示例使用
很难说,真的。受控示例:从圆形字母列表中,这将返回字典中较早出现的最短子序列的索引,而不是相同长度的任何其他子序列(假设所有字母均为小写)。
答案 1 :(得分:1)
它返回a
子字符串中元素0..n-1
范围内最小元素的位置。
答案 2 :(得分:0)
测试代码
#include <stdio.h>
int flr(int n, char a[])
{
#define A(i) a[((i) + k) % n]
int l[n], ls = n, z[n], min = 0;
for (int i = 0; i < n; i++)
{
l[i] = i;
z[i] = 1;
}
for (int k = 0; ls >= 2; k++)
{
min = l[0];
for (int i=0; i<ls; i++) min = A(l[i])<A(min) ? l[i] : min;
for (int i=0; i<ls; i++) z[A(l[i])!=A(min) ? l[i] : (l[i]+k+1)%n] = 0;
for (int ls_=ls, i=ls=0; i<ls_; i++) if (z[l[i]]) l[ls++] = l[i];
}
return ls == 1 ? l[0] : min;
}
int main() {
printf(" test 1: %d\n", flr(4, "abcd"));
printf(" test 3: %d\n", flr(6, "10e-10"));
printf(" test 3: %d\n", flr(3, "zxyghab");
printf(" test 4: %d\n", flr(5, "bcaaa"));
printf(" test 5: %d\n", flr(7, "abcd"));
return 0;
}
此代码提供以下输出:
[root@s1 sf]# ./a.out
test 1: 0
test 2: 3
test 3: 1
test 4: 2
test 5: 4
1. 0 is the position of `a` in the first case
2. 3 is the position of `-` in second case.
3. 1 is the position of `x` in third case.
4. 2 is the position of the second `a`.
5. 4 is the position of the `\0`
因此函数返回a
指向的字符指针的最小元素的位置,它将考虑n
个元素。 (这就是为什么它在第三种情况下返回x
的位置)。
但是当多个最小元素可用时,它似乎不能以可预测的方式工作,因为它不会返回第一个匹配项,也不会返回最后一个匹配项。
它应该检查超出范围的错误。这可能导致将来出现问题。
答案 3 :(得分:-1)
所以我正在对此进行测试。
int flr(int n, char a[])
{
#define A(i) a[((i) + k) % n]
int l[n], ls = n, z[n], min = 0;
for (int i = 0; i < n; i++)
{
l[i] = i;
z[i] = 1;
}
for (int k = 0; ls >= 2; k++)
{
min = l[0];
for (int i=0; i<ls; i++) min = A(l[i])<A(min) ? l[i] : min;
for (int i=0; i<ls; i++) z[A(l[i])!=A(min) ? l[i] : (l[i]+k+1)%n] = 0;
for (int ls_=ls, i=ls=0; i<ls_; i++) if (z[l[i]]) l[ls++] = l[i];
}
return ls == 1 ? l[0] : min;
}
int main()
{
int in = 10;
char array[] = {0, 1, 1, 1, 1, 1, 0, 1, 1, 0};
int res = flr(in, array);
printf("expecting res to be 6;\tres = %d\n", res);
system("pause");
return 0;
}
输出是res = 9;