Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 从排序字符串数组中查找第一个前缀匹配的最有效算法是什么?_Arrays_String_Algorithm_Sorting_Search - Fatal编程技术网

Arrays 从排序字符串数组中查找第一个前缀匹配的最有效算法是什么?

Arrays 从排序字符串数组中查找第一个前缀匹配的最有效算法是什么?,arrays,string,algorithm,sorting,search,Arrays,String,Algorithm,Sorting,Search,输入: 1) 字符串SA的巨大排序数组 2) 前缀字符串p 输出: 与输入前缀匹配的第一个字符串的索引(如果有)。 如果没有这样的匹配,那么输出将是-1 例如: SA = {"ab", "abd", "abdf", "abz"} P = "abd" 输出应为1(索引从0开始) 做这类工作最有效的算法是什么?FreeBSD内核使用a作为其路由表,您应该检查一下。这只是一个修改过的对分搜索: 只检查每个元素中与搜索字符串中相同数量的字符;及 如果找到匹配项,请继续向后搜索(线性搜索或进一步二分法

输入:

1) 字符串SA的巨大排序数组

2) 前缀字符串p

输出:

与输入前缀匹配的第一个字符串的索引(如果有)。 如果没有这样的匹配,那么输出将是-1

例如:

SA = {"ab", "abd", "abdf", "abz"}
P = "abd"
输出应为1(索引从0开始)


做这类工作最有效的算法是什么?

FreeBSD内核使用a作为其路由表,您应该检查一下。

这只是一个修改过的对分搜索:

  • 只检查每个元素中与搜索字符串中相同数量的字符;及
  • 如果找到匹配项,请继续向后搜索(线性搜索或进一步二分法搜索),直到找到不匹配的结果,然后返回最后一个匹配结果的索引

可以在线性时间内使用。构建后缀树需要线性时间。

我目前考虑的解决方案是,不要查找“前缀”,而是尝试查找“虚拟前缀”


例如,前缀为“abd”,请尝试查找虚拟前缀“abc(255)”。(255)仅表示最大字符数。找到“abc(255)”后,下一个单词应该是与“abd”匹配的第一个单词如果有的话。

如果您只想这样做一次,那么另一方面,如果您需要对许多不同的前缀(但在同一个字符串数组上)执行此操作,那么构建一个数组可能是一个好主意,在构建完树后,每次查找都会非常快。

您是否能够预先计算所有可能的前缀


如果是这样,您可以这样做,然后使用二进制搜索在预先计算的表中查找前缀。使用前缀存储所需值的下标。

我的解决方案: 使用二进制搜索

private static int search(String[] words, String searchPrefix) {

        if (words == null || words.length == 0) {
            return -1;
        }
        int low = 0;
        int high = words.length - 1;
        int searchPrefixLength = searchPrefix.length();

        while (low <= high) {
            int mid = low + (high - low) / 2;

            String word = words[mid];
            int compare = -1;

            if (searchPrefixLength <= word.length()) {
                compare = word.substring(0, searchPrefixLength).compareTo(searchPrefix);
            }

            if (compare == 0) {
                return mid;
            } else if (compare > 0) {
                high = mid - 1;
            } else {
                low = mid + 1;
            }

        }
        return -1;
    }
private静态整型搜索(String[]单词,String searchPrefix){
if(words==null | | words.length==0){
返回-1;
}
int低=0;
int-high=单词长度-1;
int searchPrefixLength=searchPrefix.length();

而(low这里是一个可能的解决方案(在Python中),它具有O(k.log(n))时间复杂度和O(1)额外的空间复杂度(考虑到n个字符串和k个前缀长度)

其基本原理是执行二进制搜索,只考虑字符串的给定字符索引。如果存在这些索引,则继续下一个字符索引。如果在任何字符串中找不到任何前缀字符,则会立即返回

输入导入列表中的

def first(项目:列表[str],前缀:str,i:int,c:str,左:int,右:int):
结果=-1
左=len(项目[mid]):
左=中+1
elif(c<项目[mid][i]):
右=中-1
elif(c>项目[mid][i]):
左=中+1
其他:
结果=中
右=中-1
返回结果
def last(项目:列表[str],前缀:str,i:int,c:str,左:int,右:int):
结果=-1
左=len(项目[mid]):
左=中+1
elif(c<项目[mid][i]):
右=中-1
elif(c>项目[mid][i]):
左=中+1
其他:
结果=中
左=中+1
返回结果
def是前缀(项目:列表[str],前缀:str):
左=0
右=透镜(项目)-1
对于范围内的i(len(前缀)):
c=前缀[i]
左=第一(项目、前缀、i、c、左、右)
右=最后(项目、前缀、i、c、左、右)
如果(左==-1或右==-1):
返回错误
返回真值
#测试用例
a=['ab','abjsiohjd','abikshdiu','ashdi','abcde Aasioudhf','abcdefgOAJ','aa','aaap','aas','asd','BBBBBBB','BSADIJH','iod','0asdn','asdjd','bqw','ba']
a、 排序()
印刷品(a)
打印(是前缀(a,'abcdf'))
打印(是前缀(a,'abcde'))
打印(是前缀(a,'abcdef'))
打印(是前缀(a,'abcdefg'))
打印(是前缀(a,'abcdefgh'))
打印(是前缀(a,'abcde Aa'))
打印(是_前缀(a,'iod'))
打印(是_前缀(a,'zzzz-iod'))

这一要点在

基树的最佳案例查找时间是O(n),其中n是字符数,而二进制搜索则是O(log m),其中m是列表的大小。基数搜索速度不一定会更快。蜘蛛纲:这不是真的。即使在最佳案例(存在匹配)中,二进制搜索也是O(n+logm),因为它必须读取整个前缀以检查是否匹配。在最坏的情况下,它是O(nlogm)。@Arachnid:+1表示布赖恩的评论,加上O(n)是对基数树的最坏情况查找,其中存在匹配项,您需要读取整个前缀。好吧,二进制搜索几乎不需要实现,并且不需要额外内存。基数树实现起来很复杂,需要额外内存,好处也不多。sortedIndex使其更简单:)他还可以在线性时间内将前缀与每个元素进行比较。没错,但如果他要检查多个前缀,那不是个好主意。