[英]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.