在 PHP 中的两个字符串中寻找相同的字符

Looking for the same chars in two strings in PHP

给定两个字符串,在 PHP 中检索共同字符和不共同字符的最佳方法是什么?

例如,给定两个字符串:

postcard

car

我想要这样的东西:

letters in common: c - a - r
letters not in common: p - o - s - t - d

我看到有单词相似度函数 return 一个数值。

但是,我想检索每个字符

我的方法是将两个字符串都视为数组(使用 str_split),然后检查最短字符串中的元素是否存在于较长的字符串中(使用 in_array)。

$arr_postcard = str_split($postcard);
$arr_car = str_split($car);
$notcommon = array();
   if (in_array($arr_postcard, $arr_car) == false){
       array_push($notcommon, $arr_car);
   }
   foreach($notcommon as $k => $v){
      print_r ($v);
   }

上面的代码似乎不起作用。它 return 是 $arr_car.

的值

也许还有其他方法。

我会选择以下内容。 拆分字符串以获得每个单独的字符,并使用值翻转键,以便所有单独的字符都是键。 (使用 array_flip

现在我们可以使用键和一些基本的集合操作,例如array_intersect_key来获取两个字符串中的字符的交集。 我们可以应用 array_diff_key 来获取集合的差异(因此那些字符在第一个字符串中但不在另一个字符串中)。

$s1 = array_flip(str_split('postcard'));
$s2 = array_flip(str_split('car'));

$intersection = array_intersect_key($s1, $s2);
$difference = array_diff_key($s1, $s2);

echo 'Letters in common: ' . implode(' - ', array_keys($intersection)) . PHP_EOL;
echo 'Letters NOT in common: ' . implode(' - ', array_keys($difference)) . PHP_EOL;

以上确实是为了吐出独特的字符(笔记集)。下面一段代码我假设是你想要实现的:

function outputResult(string $s, bool $inCommon = true)
{
    $result = 'Letters';

    if (!$inCommon) {
        $result .= ' NOT';
    }

    $result .= ' in common: ';
    $result .= !empty($s) ? implode(' - ', str_split($s)) : 'NONE';

    echo $result . PHP_EOL;
}

// Count for both the occurrences of each char.
$s1 = array_count_values(str_split('paccoi'));
$s2 = array_count_values(str_split('coi'));

$mostUniqueChars = $s1;
$leastUniqueChars = $s2;

// For now I assumed the string with most unique characters
// is the one you want to test. Could ofcourse output them both
// ways if you wrap all logic in a function. (note that intersection
// is the same both ways)
if (count($s2) > count($s1)) {
    $mostUniqueChars = $s2;
    $leastUniqueChars = $s1;
}

$intersect = '';
$diff = '';
foreach ($mostUniqueChars as $char => $count) {
    // Get the number of characters in common (and how frequent)
    $common = min($count, ($leastUniqueChars[$char] ?? 0));
    // As an alternative you could add common and difference to an array to keep
    // the counts, but I chose to repeat it and concat it to a string.
    if ($common > 0) {
        $intersect .= str_repeat($char, $common);
    }

    // Calculate the difference between first string and second string
    // in case difference has a value <= 0 then string 2 had more occurrences
    // of the character.
    $difference = $count - ($leastUniqueChars[$char] ?? 0);
    if ($difference > 0) {
        $diff .= str_repeat($char, $difference);
    }
};

// Note that both strings $intersect and $diff contain
// all the characters, you could also output these directly.
outputResult($intersect);
outputResult($diff, $inCommon = false);

输出:

Letters in common: c - o - i
Letters NOT in common: p - a - c

一个简单的方法:

<?php

$postcard = 'paccoi';
$car = 'coi';

$arr_postcard = str_split($postcard);
$arr_car = str_split($car);


function array_diff_once($array1, $array2) {
    foreach($array2 as $a) {
        $pos = array_search($a, $array1);
        if($pos !== false) {
            unset($array1[$pos]);
        }
    }

    return $array1;
}

$uncommon = count($arr_postcard) >= count($arr_car) ?  array_diff_once($arr_postcard,$arr_car) : array_diff_once($arr_car,$arr_postcard);

echo 'Letters not in common: ' . implode(' - ', $uncommon) . PHP_EOL;

function array_intersect_once($array1, $array2) {
    $array = [];
    foreach($array1 as $a) {
        $pos = array_search($a, $array2);
        if($pos !== false) {
            $array[] = $a;
        }
    }

    return $array;
}
$common = count($arr_postcard) >= count($arr_car) ?  array_intersect_once($arr_car,$arr_postcard) : array_intersect_once($arr_postcard,$arr_car);

echo 'Letters in common: ' . implode(' - ', $common) . PHP_EOL;

输出: https://3v4l.org/lY755 and https://3v4l.org/kK9sE

注意:- 您可以在 str_split() 中使用 trim() 来解决字符串前导或尾随空格的问题。

引用: Keep Duplicates while Using array_diff