在给定数组中查找字符串的最长后缀

时间:2013-08-26 08:03:35

标签: c string algorithm

给定一个字符串和字符串数组,找到数组中字符串的最长后缀。

例如

string = google.com.tr

array = tr, nic.tr, gov.nic.tr, org.tr, com.tr

返回com.tr

我曾尝试使用特定比较器进行二分查找,但失败了。

欢迎使用C代码。

编辑:

我应该说我正在寻找一个解决方案,我可以在准备步骤中做尽可能多的工作(当我只有一系列后缀时,我可以用各种可能的方式对其进行排序,构建任何数据 - 它周围的结构等。),并且比给定的字符串尽可能快地在这个数组中找到它的后缀。我也知道我可以从这个数组中构建一个trie,并且这可能会给我最好的性能,但是我非常懒惰并且在原始C中保持一个trie,在纠结的企业代码的巨大和平中是没有乐趣的。因此,一些类似binsearch的方法将非常受欢迎。

5 个答案:

答案 0 :(得分:1)

假设字符串中字符的持续时间寻址,这个问题与查找最大前缀是同构的。

  1. i = 0

  2. S = null

  3. c = prefix[i]

  4. 如果aA,请从a[i] != c删除字符A。如果S

  5. ,请将a替换为a.Length == i + 1
  6. 增量i

  7. 转到第3步。

  8. 这就是你要找的东西吗?


    示例:

    prefix = rt.moc.elgoog

    array = rt.moc,rt.org,rt.cin.vof,rt.cin,rt

    传递0:prefix[0]'r'array[j][0] == 'r'j,因此不会从数组中删除任何内容。 i + 1 -> 0 + 1 -> 1是我们的目标长度,但没有一个字符串的长度为1,因此S仍为null

    通过1:prefix[1] 't'array[j][1] == 'r'适用于所有j,因此不会从阵列中删除任何内容。但是,有一个长度为2的字符串,因此S变为rt

    传递2:prefix[2]'.'array[j][2] == '.'为其余字符串,因此没有任何变化。

    通过3:prefix[3]'m'array[j][3] != 'm'rt.orgrt.cin.vofrt.cin,因此会删除这些字符串。

答案 1 :(得分:0)

天真,伪答案:

  1. 按长度排序后缀数组(是的,可能会有相同长度的字符串,这是您认为我问的问题的问题)
  2. 遍历数组并查看后缀是否在给定字符串中
  3. 如果是,请退出循环,因为你已经完成了!如果没有,请继续。
  4. 或者,您可以跳过排序并进行迭代,如果biggestString大于匹配的currentString,则指定biggestString

    编辑0:

    也许你可以通过预先查看你的数组并考虑需要检查的“最小”元素来改进这一点。

    例如,如果.com出现在20个成员中,您只需针对给定字符串检查.com即可消除20个候选人。

    编辑1:

    第二个想法,为了比较数组中的元素,您需要使用字符串比较。我的感觉是,在尝试优化字符串列表以进行比较时获得的任何收益可能会因为在这样做之前比较它们的代价而被否定,如果这有意义的话。如果CS类型可以在这里纠正我,我将不胜感激......

答案 2 :(得分:0)

另一个天真的,伪答案。

将布尔“找到”设置为false。当“found”为false时,迭代数组,将源字符串与数组中的字符串进行比较。如果匹配,请将“found”设置为true并中断。如果没有匹配项,请使用strchr()之类的内容来访问第一个句点之后的字符串段。再次迭代数组。继续直到匹配,或直到源字符串的最后一段与阵列中的所有字符串进行比较并且无法匹配。

效率不高......

答案 3 :(得分:0)

如果你的字符串数组如下:

char string[STRINGS][MAX_STRING_LENGTH];
string[0]="google.com.tr";
string[1]="nic.tr";

等,然后你可以这样做:

int x, max = 0;

for (x = 0; x < STRINGS; x++) {
    if (strlen(string[x]) > max) {
        max = strlen(string[x]);
    }
}

x = 0;

while(true) {
    if (string[max][x] == ".") {
       GOTO out;
    }
    x++;
}

out:

char output[MAX_STRING_LENGTH];
int y = 0;

while (string[max][x] != NULL) {
    output[y++] = string[++x];
}

(上面的代码可能实际上不起作用(错误等),但你应该得到一般的想法。

答案 4 :(得分:0)

为什么不使用后缀数组?当你有大量的后缀时它会起作用。

复杂性,O(n(logn)^2),也有O(nlogn)个版本。

c here中的实施。您也可以尝试使用googling后缀数组。