Php 在数组中查找相似字符串

Php 在数组中查找相似字符串,php,arrays,similarity,Php,Arrays,Similarity,我需要利用一个类似以下内容的值数组: $strings = ["lawyer" => 3, "business" => 3, "lawyers" => 1, "a" => 3]; 我想做的是在上面的数组中找到几乎相同的单词,即律师和律师,并将它们的计数加在一个新数组中 因此律师将是4,因为律师将与律师的原始字符串相关联 请记住,此数组将仅为单数单词,且长度未指定,其范围可能为1到>99 我不知道从哪里开始,所以我用foreach循环对它进行了一次破解,如下所示,但是预期

我需要利用一个类似以下内容的值数组:

$strings = ["lawyer" => 3, "business" => 3, "lawyers" => 1, "a" => 3];
我想做的是在上面的数组中找到几乎相同的单词,即
律师
律师
,并将它们的计数加在一个新数组中

因此
律师
将是
4
,因为
律师
将与
律师
的原始字符串相关联

请记住,此数组将仅为单数单词,且长度未指定,其范围可能为
1
>99

我不知道从哪里开始,所以我用foreach循环对它进行了一次破解,如下所示,但是预期的输出并不像预期的那样

foreach ( $strings as $key_one => $count_one ) {
    foreach ( $strings as $key_two => $count_two ) {
        similar_text($key_two, $key_one, $percent);
        if ($percent > 80) {
            if(!isset($counts[$key_one])) {
                $counts[$key_one] = $count_one;
            } else {
                $counts[$key_one] += $count_two;
            }
        }
    }
}
注意:本例中的匹配百分比为
80
(因为
律师
律师
的匹配百分比为
~92%

这最终给了我类似于以下的东西:

Array
(
    [lawyer] => 4
    [business] => 3
    [a] => 3
    [lawyers] => 2
)
如果我要求:

Array
(
    [lawyer] => 4
    [business] => 3
    [a] => 3
)
请注意,我如何要求它实际删除
律师
,并将计数添加到
律师

,您可以随时使用

unset( $counts[$key_two] ) ;
你可以随时使用

unset( $counts[$key_two] ) ;
你可以随时使用

unset( $counts[$key_two] ) ;
你可以随时使用

unset( $counts[$key_two] ) ;

你们的困难在于,正如律师和律师相似一样,律师也和律师相似。所以他们两人的人数都被另一个增加了

试试这个:

foreach ( $strings as $key_one => &$count_one ) {
    if ($count_one == 0) continue; // skip it if we've already processed it
    if (!isset($counts[$key_one]) {
        $counts[$key_one] = $count_one;
        $count_one = 0;
    }
    foreach ( $strings as $key_two => &$count_two ) {
        similar_text($key_two, $key_one, $percent);
        if ($percent > 80) {
            $counts[$key_one] += $count_two;
            $count_two = 0;
        }
    }
}
这样做的缺点是更改了原始的$strings数组,这可能并不理想。下面是另一种方法,在另一个哈希中跟踪已处理的字符串:

$already = $counts = array(); // not really necessary, but nice to init
foreach ( $strings as $key_one => $count_one ) {
    if (isset($already[$key_one])) continue; // skip if already processed
    $counts[$key_one] = $count_one; // by definition this should be new
    foreach ( $strings as $key_two => $count_two ) {
        similar_text($key_two, $key_one, $percent);
        if ($percent > 80) {
            $counts[$key_one] += $count_two;
            $already[$key_two] = true;
        }
    }
}

我推荐第二种解决方案。

你的困难在于,正如律师与律师相似一样,律师也与律师相似。所以他们两人的人数都被另一个增加了

试试这个:

foreach ( $strings as $key_one => &$count_one ) {
    if ($count_one == 0) continue; // skip it if we've already processed it
    if (!isset($counts[$key_one]) {
        $counts[$key_one] = $count_one;
        $count_one = 0;
    }
    foreach ( $strings as $key_two => &$count_two ) {
        similar_text($key_two, $key_one, $percent);
        if ($percent > 80) {
            $counts[$key_one] += $count_two;
            $count_two = 0;
        }
    }
}
这样做的缺点是更改了原始的$strings数组,这可能并不理想。下面是另一种方法,在另一个哈希中跟踪已处理的字符串:

$already = $counts = array(); // not really necessary, but nice to init
foreach ( $strings as $key_one => $count_one ) {
    if (isset($already[$key_one])) continue; // skip if already processed
    $counts[$key_one] = $count_one; // by definition this should be new
    foreach ( $strings as $key_two => $count_two ) {
        similar_text($key_two, $key_one, $percent);
        if ($percent > 80) {
            $counts[$key_one] += $count_two;
            $already[$key_two] = true;
        }
    }
}

我推荐第二种解决方案。

你的困难在于,正如律师与律师相似一样,律师也与律师相似。所以他们两人的人数都被另一个增加了

试试这个:

foreach ( $strings as $key_one => &$count_one ) {
    if ($count_one == 0) continue; // skip it if we've already processed it
    if (!isset($counts[$key_one]) {
        $counts[$key_one] = $count_one;
        $count_one = 0;
    }
    foreach ( $strings as $key_two => &$count_two ) {
        similar_text($key_two, $key_one, $percent);
        if ($percent > 80) {
            $counts[$key_one] += $count_two;
            $count_two = 0;
        }
    }
}
这样做的缺点是更改了原始的$strings数组,这可能并不理想。下面是另一种方法,在另一个哈希中跟踪已处理的字符串:

$already = $counts = array(); // not really necessary, but nice to init
foreach ( $strings as $key_one => $count_one ) {
    if (isset($already[$key_one])) continue; // skip if already processed
    $counts[$key_one] = $count_one; // by definition this should be new
    foreach ( $strings as $key_two => $count_two ) {
        similar_text($key_two, $key_one, $percent);
        if ($percent > 80) {
            $counts[$key_one] += $count_two;
            $already[$key_two] = true;
        }
    }
}

我推荐第二种解决方案。

你的困难在于,正如律师与律师相似一样,律师也与律师相似。所以他们两人的人数都被另一个增加了

试试这个:

foreach ( $strings as $key_one => &$count_one ) {
    if ($count_one == 0) continue; // skip it if we've already processed it
    if (!isset($counts[$key_one]) {
        $counts[$key_one] = $count_one;
        $count_one = 0;
    }
    foreach ( $strings as $key_two => &$count_two ) {
        similar_text($key_two, $key_one, $percent);
        if ($percent > 80) {
            $counts[$key_one] += $count_two;
            $count_two = 0;
        }
    }
}
这样做的缺点是更改了原始的$strings数组,这可能并不理想。下面是另一种方法,在另一个哈希中跟踪已处理的字符串:

$already = $counts = array(); // not really necessary, but nice to init
foreach ( $strings as $key_one => $count_one ) {
    if (isset($already[$key_one])) continue; // skip if already processed
    $counts[$key_one] = $count_one; // by definition this should be new
    foreach ( $strings as $key_two => $count_two ) {
        similar_text($key_two, $key_one, $percent);
        if ($percent > 80) {
            $counts[$key_one] += $count_two;
            $already[$key_two] = true;
        }
    }
}

我推荐第二种解决方案。

为什么不将其转换为oop?然后您可以注册和取消注册对象。与所有单词最初注册到对象主控形状一样,如果找到匹配项,则将从主控形状中删除匹配项,并重新注册到匹配项。通过这种方式,您可以保留这些值,并在需要时动态插入单词。也许您想看看Levenshtein距离算法@Michaeldibtes谢谢您的评论!我现在已经知道了如何获取它,我只需要从数组中删除该项,这样就不会在新创建的数组中设置它。如果你想把它作为一个答案,我会接受的。@RaphaelMüller也谢谢你的评论,我读过维基,它是一个相当有趣的算法。你为什么不把它转换成oop呢?然后您可以注册和取消注册对象。与所有单词最初注册到对象主控形状一样,如果找到匹配项,则将从主控形状中删除匹配项,并重新注册到匹配项。通过这种方式,您可以保留这些值,并在需要时动态插入单词。也许您想看看Levenshtein距离算法@Michaeldibtes谢谢您的评论!我现在已经知道了如何获取它,我只需要从数组中删除该项,这样就不会在新创建的数组中设置它。如果你想把它作为一个答案,我会接受的。@RaphaelMüller也谢谢你的评论,我读过维基,它是一个相当有趣的算法。你为什么不把它转换成oop呢?然后您可以注册和取消注册对象。与所有单词最初注册到对象主控形状一样,如果找到匹配项,则将从主控形状中删除匹配项,并重新注册到匹配项。通过这种方式,您可以保留这些值,并在需要时动态插入单词。也许您想看看Levenshtein距离算法@Michaeldibtes谢谢您的评论!我现在已经知道了如何获取它,我只需要从数组中删除该项,这样就不会在新创建的数组中设置它。如果你想把它作为一个答案,我会接受的。@RaphaelMüller也谢谢你的评论,我读过维基,它是一个相当有趣的算法。你为什么不把它转换成oop呢?然后您可以注册和取消注册对象。与所有单词最初注册到对象主控形状一样,如果找到匹配项,则将从主控形状中删除匹配项,并重新注册到匹配项。通过这种方式,您可以保留这些值,并在需要时动态插入单词。也许您想看看Levenshtein距离算法@Michaeldibtes谢谢您的评论!我现在已经知道了如何获取它,我只需要从数组中删除该项,这样就不会在新创建的数组中设置它。如果你想把它作为一个答案,我会接受的。@RaphaelMüller也谢谢你的评论,我读过维基,它是一个相当有趣的算法。