簡體   English   中英

最佳字符串,其中包含給定集中的所有字符串作為子字符串

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM