用法:
$ex = new finder($string);
$result = $ex->search(979)->find(true); // true = Hard mode
首先我们传递我们要搜索的字符串,然后我们使用方法 to_array() 以便我们可以从字符串创建数组,然后您需要选择要使用的模式。
它有两种模式,软搜索和硬搜索。
在find方法中可以选择使用哪一种,->find(true),True=硬模式,False=软模式;
软模式非常简单,创建一个新的多维数组,其中键作为数字的 strlen(方法 order()),所以如果我们要搜索数字 70,我们真的不想使用 3 位数字或更多,我的意思是(100、99999 等...)。然后它只是用数字减去搜索值,如果有结果,则尝试用 (in_array) 在整个数组中搜索;
foreach ($this->_clean as $clean) {
$minus = abs($clean - $search);
// Simple and fast query
if(in_array($minus, $this->_clean)){
$tmp[] = array($minus,$clean);
}
}
困难模式就像名字所说的那样,我们将遍历每个数字。
public function hard_search($array, $partial){
$s = 0;
foreach ($partial as $x){
$s += $x;
}
if ($s == $this->_search){
$this->_tmp[] = $partial;
}
if ($s < $this->_search){
for($i=0;$i<count($array);$i++) {
$remaining = array();
$n = $array[$i];
for ($j=$i+1; $j<count($array); $j++) {
array_push($remaining, $array[$j]);
};
$partial_rec = $partial;
array_push($partial_rec, $n);
$this->hard_search($remaining,$partial_rec);
}
}
return $this->_tmp;
}
当然,我们真的可以再做一些调整,但从我测试的结果来看,它给出了很好的结果。
如果您有任何问题,请随时提出。
输出示例:http://codepad.viper-7.com/INvSNo
class finder {
public $stop;
protected $_string,
$_search,
$_tmp,
$_array = array(),
$_array_order = array(),
$_clean = array();
public function __construct($string){
$this->_string = $string;
}
/**
* String to array
*
* @return \find
*/
public function to_array(){
$this->_array = array_keys(
array_flip(
explode(' ', $this->_string)
)
);
return $this;
}
/**
* what we are searching for
*
* @param string/int $search
* @return \finder
*/
public function search($search){
$this->reset();
$this->_search = $search;
$this->to_array();
return $this;
}
/**
*
* @param type $a // array
* @param type $total // total
* @return array
*/
public function find($hard = false){
$this->_hard = $hard;
if(is_array($this->_search)){
foreach($this->_search as $search){
$result[] = $this->search_array($search);
}
}else{
$result = $this->search_array($this->_search);
}
return $result;
}
/**********************************
* SOFT SEARCH
***********************************/
/**
* Multidimensional Array with strlen as the key
*
* @return \find
*/
public function order(){
// Order
foreach($this->_array as $n){
$this->_array_order[strlen($n)][] = $n;
}
return $this;
}
public function clean($search){
$tmp = array();
$check_length = function($number) use($search){
if($number <= $search){
return $number;
}
return false;
};
foreach(range(key($this->_array_order), strlen($search)) as $v){
$tmp = array_map($check_length,array_merge($tmp, $this->_array_order[$v]));
}
$this->_clean = array_filter($tmp);
sort($this->_clean);
return $this;
}
public function search_array($search) {
$res = array();
if($this->_hard == false){
$this->order();
$this->clean($search);
$res = $this->soft_search($search);
}else{
$res = $this->hard_search($this->_array, array());
}
return $res;
}
/**
*
* @return array
*/
public function soft_search($search){
$tmp = array();
foreach ($this->_clean as $clean) {
$minus = abs($clean - $search);
// Simple and fast query
if(in_array($minus, $this->_clean)){
$tmp[] = array($minus,$clean);
}
}
return $tmp;
}
/**********************************
* END SOFT SEARCH
***********************************/
public function hard_search($array, $partial){
$s = 0;
foreach ($partial as $x){
$s += $x;
}
if ($s == $this->_search){
$this->_tmp[] = $partial;
}
// if higher STOP
if ($s < $this->_search){
for($i=0;$i<count($array);$i++) {
$remaining = array();
$n = $array[$i];
for ($j=$i+1; $j<count($array); $j++) {
array_push($remaining, $array[$j]);
};
$partial_rec = $partial;
array_push($partial_rec, $n);
$this->hard_search($remaining,$partial_rec);
}
}
return $this->_tmp;
}
/****************************
*
* Extra
*
*****************************/
public function reset(){
$this->_search = '';
$this->_clean = array();
$this->_array = array();
$this->_array_order = array();
$this->_tmp = array();
$this->_tmp = array();
return $this;
}
public function new_string($string){
$this->reset();
$this->_string = $string;
$this->to_array();
return $this;
}
}
$string = '70 58 81 909 70 215 130 70 1022 580 930 898 70 276 31 11 920 898 1503 195 770 573 508 '
. '1171 490 565 55 108';
$ex = new finder($string);
echo '<pre>';
echo '<h1>Hard 979</h1>';
$result = $ex->search(979)->find(true);
print_r($result);
echo '<h1>Soft 979</h1>';
$result = $ex->search(979)->find();
print_r($result);
echo '<h1>Hard 238</h1>';
$result = $ex->search(238)->find(true);
print_r($result);
echo '<h1>Soft 238</h1>';
$result = $ex->search(238)->find();
print_r($result);
285 的输出示例:
Hard 285
Array
(
[0] => Array
(
[0] => 70
[1] => 215
)
[1] => Array
(
[0] => 58
[1] => 130
[2] => 31
[3] => 11
[4] => 55
)
)
Soft 285
Array
(
[0] => Array
(
[0] => 215
[1] => 70
)
)