【问题标题】:PHP - Group Strings By Similarity / Substring [closed]PHP - 按相似性/子字符串分组字符串[关闭]
【发布时间】:2017-08-03 08:55:35
【问题描述】:

PHP

您好,我一直在努力解决这个问题,但找不到解决方案,想知道是否有人可以提供帮助。

我需要对类似的字符串进行分组,例如:

输入

纤细铝制 HDMI 引线,1m 蓝色
细长铝制 HDMI 引线,2m 蓝色
纤细铝制 HDMI 引线,3m 蓝色
带音量限制器的冷冻儿童耳机
XLR 插头到插座引线,3m
XLR 插头到插座引线,6m
带音量限制器的 Monster High 儿童耳机
带音量限制器的 TMNT 儿童耳机
带音量限制器的蝙蝠侠儿童耳机
1 联电缆入口刷墙板白色/白色刷子 50 x 45 毫米
2 联电缆入口刷墙板白色/白色刷子 50 x 100mm
1 联电缆入口刷墙板白色/黑色刷子 50 x 45 毫米
2 联电缆入口刷墙板白色/黑色刷子 50 x 100 毫米
细长铝制 HDMI 引线,5m 蓝色
细长铝制 HDMI 引线,7.5m 蓝色
6.35 毫米(1/4 英寸)单声道插孔到插孔吉他引线,5m 橙色
XLR 插头到插座引线,0.5m
XLR 插头到插座引线,1m
XLR 插头到插座引线,2m

输出(按数组分组)

纤细铝制 HDMI 引线,1m 蓝色
细长铝制 HDMI 引线,2m 蓝色
纤细铝制 HDMI 引线,3m 蓝色
细长铝制 HDMI 引线,5m 蓝色
超薄铝制 HDMI 引线,7.5m 蓝色

XLR 插头到插座引线,0.5m
XLR 插头到插座引线,1m
XLR 插头到插座引线,2m
XLR 插头到插座引线,3m
XLR 插头到插座引线,6m

1-Gang 电缆入口刷墙板白色/白色刷子 50 x 45mm
2 联电缆入口刷墙板白色/白色刷子 50 x 100mm
1 联电缆入口刷墙板白色/黑色刷子 50 x 45 毫米
2 联电缆入口刷墙板白色/黑色刷子 50 x 100mm

带音量限制器的冷冻儿童耳机
带音量限制器的 Monster High 儿童耳机
带音量限制器的 TMNT 儿童耳机
带音量限制器的蝙蝠侠儿童耳机

6.35 毫米(1/4 英寸)单声道插孔到插孔吉他引线,5m 橙色

【问题讨论】:

  • 到目前为止你尝试了什么?你用过 PHP 的similar_text() 函数吗?
  • 我也刚刚发现了 levenshtein() 函数,可能值得研究
  • @Paul 我已经尝试过similar_text() 但无法使其正常工作,结果可能是随机的。
  • 我已经用更好的解决方案更新了我的答案,我应该一次选择一个单词并找到匹配项,从池中删除匹配项,而不是尝试排序然后再做一个彼此。

标签: php string substring grouping similarity


【解决方案1】:

更新:我找到了更好的解决方案

我从来没有玩过 php 的similar_text() 函数,但我想我会试一试...

$array = explode(PHP_EOL,'Slim Aluminium HDMI Lead, 1m Blue
Slim Aluminium HDMI Lead, 2m Blue
Slim Aluminium HDMI Lead, 3m Blue
Frozen Kids Headphones with Volume Limiter
XLR Plug to Socket Lead, 3m
XLR Plug to Socket Lead, 6m
Monster High Kids Headphones with Volume Limiter
TMNT Kids Headphones with Volume Limiter
Batman Kids Headphones with Volume Limiter
1-Gang Cable Entry Brush Wall Plate White/White Brushes 50 x 45mm
2-Gang Cable Entry Brush Wall Plate White/White Brushes 50 x 100mm
1-Gang Cable Entry Brush Wall Plate White/Black Brushes 50 x 45mm
2-Gang Cable Entry Brush Wall Plate White/Black Brushes 50 x 100mm
Slim Aluminium HDMI Lead, 5m Blue
Slim Aluminium HDMI Lead, 7.5m Blue
6.35mm (1/4") Mono Jack to Jack Guitar Lead, 5m Orange
XLR Plug to Socket Lead, 0.5m
XLR Plug to Socket Lead, 1m
XLR Plug to Socket Lead, 2m');

$output = array();
while( empty( $array ) === false )
{
  $currentWord = array_shift( $array );
  $currentGroup = array( $currentWord );
  foreach( $array as $index => $word )
  {
    if( similar_text( $word, $currentWord, $percentage ) and $percentage > 80 )
    {
      $currentGroup[] = $word;
      unset( $array[ $index ] );
    }
  }
  $output[] = $currentGroup;
}

print_r($output);

// Array
// (
//     [0] => Array
//         (
//             [0] => Slim Aluminium HDMI Lead, 1m Blue
//             [1] => Slim Aluminium HDMI Lead, 2m Blue
//             [2] => Slim Aluminium HDMI Lead, 3m Blue
//             [3] => Slim Aluminium HDMI Lead, 5m Blue
//             [4] => Slim Aluminium HDMI Lead, 7.5m Blue
//         )
// 
//     [1] => Array
//         (
//             [0] => Frozen Kids Headphones with Volume Limiter
//             [1] => Monster High Kids Headphones with Volume Limiter
//             [2] => TMNT Kids Headphones with Volume Limiter
//             [3] => Batman Kids Headphones with Volume Limiter
//         )
// 
//     [2] => Array
//         (
//             [0] => XLR Plug to Socket Lead, 3m
//             [1] => XLR Plug to Socket Lead, 6m
//             [2] => XLR Plug to Socket Lead, 0.5m
//             [3] => XLR Plug to Socket Lead, 1m
//             [4] => XLR Plug to Socket Lead, 2m
//         )
// 
//     [3] => Array
//         (
//             [0] => 1-Gang Cable Entry Brush Wall Plate White/White Brushes 50 x 45mm
//             [1] => 2-Gang Cable Entry Brush Wall Plate White/White Brushes 50 x 100mm
//             [2] => 1-Gang Cable Entry Brush Wall Plate White/Black Brushes 50 x 45mm
//             [4] => 2-Gang Cable Entry Brush Wall Plate White/Black Brushes 50 x 100mm
//         )
// 
//     [4] => Array
//         (
//             [0] => 6.35mm (1/4") Mono Jack to Jack Guitar Lead, 5m Orange
//         )
// 
// )

关联数组编辑

$products = array(
  array('id'=>'A','name'=>'Slim Aluminium HDMI Lead, 1m Blue'),
  array('id'=>'B','name'=>'Slim Aluminium HDMI Lead, 2m Blue'),
  array('id'=>'C','name'=>'Slim Aluminium HDMI Lead, 3m Blue'),
  array('id'=>'D','name'=>'1-Gang Cable Entry Brush Wall Plate White/White Brushes 50 x 45mm'),
  array('id'=>'E','name'=>'2-Gang Cable Entry Brush Wall Plate White/White Brushes 50 x 100mm'),
  array('id'=>'F','name'=>'1-Gang Cable Entry Brush Wall Plate White/Black Brushes 50 x 45mm'),
  array('id'=>'G','name'=>'2-Gang Cable Entry Brush Wall Plate White/Black Brushes 50 x 100mm'),
  array('id'=>'H','name'=>'Slim Aluminium HDMI Lead, 5m Blue'),
  array('id'=>'I','name'=>'Slim Aluminium HDMI Lead, 7.5m Blue')
);
$output = array();
while( empty( $products) === false )
{
  $currentProduct = array_shift( $products );
  $currentGroup = array( $currentProduct );
  foreach( $products as $index => $product )
  {
    if( similar_text( $product['name'], $currentProduct['name'], $percentage ) and $percentage > 80 )
    {
      $currentGroup[] = $product;
      unset( $products[ $index ] );
    }
  }
  $output[] = $currentGroup;
}
print_r($output);

【讨论】:

  • 在 while 循环处理之前加入 sort($array) 以获得不错的结果。
  • 这很好用,非常感谢 :)
  • 很抱歉再次打扰您,我将如何调整它以使用 assoc 数组,而不仅仅是开头的字符串数组,例如如果字符串名称在子索引中,例如:[0] => Array([id] => 4578, [name] => Slim Aluminum HDMI Lead, 1m Blue)
  • 我最后一次编辑 :)
猜你喜欢
  • 2017-02-25
  • 2019-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-19
  • 1970-01-01
  • 2012-07-15
  • 1970-01-01
相关资源
最近更新 更多