[英]Optimal string containing all strings from a given set as substrings
我正在使用一些需要大(恒定)位数组的代码。 由于它包含较大的常数跨度(全0或全1),因此将其分为两级表,可以消除重复的跨度(常数或其他),如下所示:
bitn = table2[table1[n/256]+n%256/8]&1<<n%8
此时,表table1
条目都是32(256位)的倍数,但我想知道是否可以通过允许table2
的跨度重叠来实现显着的节省。 所以我的问题是(以抽象形式表示):
给定N个每个长度为K的字符串{S_n:n = 1..N},是否有一种有效的方法来找到最短长度的字符串S,以使每个S_n是S的子字符串?
(请注意,由于我可能想使我的位数组保持8位对齐,因此我对该问题的特殊应用可能是处理8位字节的字符串,而不是位字符串,但是该问题在任何意义上都是有意义的-位,字节或其他内容。)
首先,可以将这个问题表述为TSP。 我们有一组节点(每个字符串是一个节点),我们需要找到访问所有节点的路径。 字符串x和y之间的距离定义为len(xy)+ len(y),其中xy是同时具有x和y且以x开头的最佳字符串(例如x = 000111,y = 011100,xy = 0001100 ,距离(x,y)= 8-6 = 2)。
注意,这也服从三角形不等式(distance(x,z)<= distance(x,y)+ distance(y,z))。 距离是1到k的整数。 而且,距离是不对称的。
TSP的此版本称为(1,B)-ATSP。 有关此类问题的分析和近似解决方案,请参见http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.20.3439 。
与具有大量常量部分的大型常量位数组有关,这是设计表供您考虑的另一种方法(我不知道您的确切需求,因此无法说出是否有帮助)。
考虑像基数树之类的东西。 为了便于说明,让我定义get函数:
#define TYP_CONST
#define TYP_ARRAY
struct node {
unsigned min;
unsigned max;
int typ;
union {
char *bits;
int constant;
} d;
struct node *left;
struct node *right;
}
struct bit_array {
unsigned length;
struct node *root;
}
int get(struct bit_array *b, unsigned ix)
{
struct node *n = b->root;
if (ix >= b->length)
return -1;
while (n) {
if (ix > n->max) {
n = n->right;
continue;
} else if (ix < n->min) {
n = n->left;
continue;
}
if (n->typ == TYP_CONST)
return n->d.constant;
ix -= n->min;
return !!(n->d.bits[ix/8] & (1 << ix%8));
}
return -1;
}
用人类的话来说,您想在树中搜索自己的位。 每个节点负责一个位范围,您可以对范围进行二进制搜索以找到所需的范围。
找到范围后,有两个选择:常数或数组。 如果为常量,则只需返回常量(可以节省大量内存)。 如果是数组,则在位数组中进行数组查找。
您将拥有O(log n)查找时间,而不是O(1)....,尽管它仍然应该非常快。
这里的困难在于设置适当的数据结构很烦人并且容易出错。 但是您说数组是恒定的,所以这可能不是问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.