算法学习-上篇 (基于PHP)

做程序其实算法很重要,处理问题也要追求一个好的算法方能事半功倍;下面我举几个我敲过的算法实例

1、可用于并发处理:
/* 
	*	PHP 代码,确保多个进程同时写入同一个文件成功
	*	核心思路:文件加锁
	*	函数介绍:
	*	(1)fopen — 打开文件或者 URL    resource fopen ( string $filename , string $mode [, bool $use_include_path = false [, resource $context ]] )
	*	'w+' 读写方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。 
	*	成功时返回文件指针资源,如果打开失败,本函数返回 FALSE
	*	(2)flock — 轻便的咨询文件锁定 bool flock ( resource $handle , int $operation [, int &$wouldblock ] )
	*	operation:LOCK_EX 取得独占锁定(写入的程序。即排它型锁定
	*	operation:LOCK_UN 释放锁定(无论共享或独占)
	*	arithmetic
	*/
	$fp = fopen('./1.txt','w+');
	if(flock($fp,LOCK_EX)){
		// 获取到写锁,写数据
		fwrite($fp,'qinruilovechuanggege');
		// 释放锁定
		flock($fp, LOCK_UN);
	}else{
		echo '有人正在使用文件';
	}
	fclose($fp);

2、双向队列
<?php
	/* 
	*	PHP  实现一个双向队列
	*	函数介绍:
	*	(1)array_unshift    array_unshift — 在数组开头插入一个或多个单元
	*	array_unshift(array,value1,value2,value3...); 
	*	array_unshift() 将传入的单元插入到 array 数组的开头。
	*	注意单元是作为整体被插入的,因此传入单元将保持同样的顺序。
	*	所有的数值键名将修改为从零开始重新计数,所有的文字键名保持不变。
	*	(2)array_push — array_push — 将一个或多个单元压入数组的末尾(入栈) 
	*	array_push($stack, "apple", "raspberry");
	*	(3)array_shift array_shift — 将数组开头的单元移出数组 
	*	所有的数字键名将改为从零开始计数
	*	将 array 的第一个单元移出并作为结果返回
	*	(4)array_pop  array_pop — 将数组最后一个单元弹出(出栈)
	*	 弹出并返回 array 数组的最后一个单元
	*	arithmetic
	*/
	class Deque{
		private $queue = array();
		public function addFirst($item){
			return array_unshift($this->queue, $item);
		}
		public function addLast($item){
			return array_push($this->queue, $item);
		}
		public function removeFirst(){
			return array_shift($this->queue);
		}
		public function removeLast(){
			return array_pop($this->queue);
		}
	}
?>

3、二维数组排序(很常用哦)
<?php
	/* 
	*	写一个二维数组排序算法函数,能够具有通用性,可以调用 php 内置函数
	*	二维数组排序, $arr是数据,$keys是排序的健值,$order是排序规则,1是升序,0是降序
	*	函数介绍:
		详见下面的说明
	*	arithmetic
	*/
function array_sort($arr, $keys, $order=0) {
	if (!is_array($arr)) {
		return false;
	}
	$keysvalue = array();
	foreach($arr as $key => $val) {
		$keysvalue[$key] = $val[$keys];
	}
	if($order == 0){
		asort($keysvalue);
	}else {
		arsort($keysvalue);
	}
	reset($keysvalue);
	foreach($keysvalue as $key => $vals) {
		$keysort[$key] = $key;
	}
	$new_array = array();
	foreach($keysort as $key => $val) {
		$new_array[$key] = $arr[$val];
	}
	return $new_array;
}
?>

注意多维数组的排序还少不了 array_mutisort

1、array_multisort的用法:

<?php
$arr1 = array(
    '0' => array('a' => 3, 'b' => 20, 'c' => 2, 'd' => 6),
    '1' => array('a' => 3, 'b' => 2, 'c' => 2, 'd' => 6),
    '2' => array('a' => 3, 'b' => 22, 'c' => 2, 'd' => 6),
    '3' => array('a' => 3, 'b' => 25, 'c' => 2, 'd' => 6),
    '4' => array('a' => 3, 'b' => 28, 'c' => 2, 'd' => 6),
    '5' => array('a' => 3, 'b' => 3, 'c' => 2, 'd' => 6),
);

$arr2 = array(
    'e1' => array('a' => 3, 'b' => 20, 'c' => 2, 'd' => 6),
    'e2' => array('a' => 3, 'b' => 2, 'c' => 2, 'd' => 6),
    'e3' => array('a' => 3, 'b' => 22, 'c' => 2, 'd' => 6),
    'e4' => array('a' => 3, 'b' => 25, 'c' => 2, 'd' => 6),
    'e5' => array('a' => 3, 'b' => 28, 'c' => 2, 'd' => 6),
    'e6' => array('a' => 3, 'b' => 3, 'c' => 2, 'd' => 6),
);

//提取列数组;foreach ($arr1 as $key => $val) {
    $tmp[$key] = $val['b'];
}

array_multisort($tmp,SORT_DESC,$arr1);
echo "<pre>";
    print_r($arr1);
echo "</pre>";

array_multisort($tmp,SORT_DESC,$arr2);
echo "<pre>";
    print_r($arr2);
echo "</pre>";

?>


2、普通sort的用法:

<?php
$arr1 = array(
    '0' => array('a' => 3, 'b' => 20, 'c' => 2, 'd' => 6),
    '1' => array('a' => 3, 'b' => 2, 'c' => 2, 'd' => 6),
    '2' => array('a' => 3, 'b' => 22, 'c' => 2, 'd' => 6),
    '3' => array('a' => 3, 'b' => 25, 'c' => 2, 'd' => 6),
    '4' => array('a' => 3, 'b' => 28, 'c' => 2, 'd' => 6),
    '5' => array('a' => 3, 'b' => 3, 'c' => 2, 'd' => 6),
);

$arr2 = array(
    'e1' => array('a' => 3, 'b' => 20, 'c' => 2, 'd' => 6),
    'e2' => array('a' => 3, 'b' => 2, 'c' => 2, 'd' => 6),
    'e3' => array('a' => 3, 'b' => 22, 'c' => 2, 'd' => 6),
    'e4' => array('a' => 3, 'b' => 25, 'c' => 2, 'd' => 6),
    'e5' => array('a' => 3, 'b' => 28, 'c' => 2, 'd' => 6),
    'e6' => array('a' => 3, 'b' => 3, 'c' => 2, 'd' => 6),
);

function array_sort($array,$keys,$type='asc'){
    //$array为要排序的数组,$keys为要用来排序的键名,$type默认为升序排序$keysvalue = $new_array = array();

    //提取排序的列foreach ($array as $k=>$v){
        $keysvalue[$k] = $v[$keys];
    }
    if($type == 'asc'){
        asort($keysvalue);//升序排列
    }else{
        arsort($keysvalue);//降序排列
    }
    //reset($keysvalue);foreach ($keysvalue as $k=>$v){
        $new_array[$k] = $array[$k];
    }
    return $new_array;
}
$arr = array_sort($arr1,'b','desc'); //此处对数组进行降序排列



思路总结:

总体的想法是这样的,要对一个多维数组按照某一个键值对排序,关键是先确定这个键值对的顺序,然后按照这个键值对的顺序去排列这个多维数组。

对于是数字索引的数组,第二种方法还是比较好的,因为它会保持数字索引,这个很好,而第一种就会把数字索引的数组重新建立数字索引;

对于是字符串索引的数组,两种方法都可以采用,完全看个人爱好。

接下来简单讲解array_multisort的参数。这个函数的参数很灵活。最简单的情况是如上面所示的以1个或n个数组作为参数,需要注意的是每个数组的项数要一样,否则会warning导致排序失效。
像这样array_multisort($arr1,$arr2,$arr3); 默认是所有数组都是升序排列,如果想对$arr2降序,并当作字符串去比较,就要写成:
array_multisort($arr1, $arr2, SORT_DESC, SORT_STRING, $arr3);
每个array后面可以跟一个排序顺序标志或一个排序类型标志,或者两种标志同时出现。但是每种排序标志在每个数组后面只能出现一个。

详细如下:
排序顺序标志:
SORT_ASC - 按照上升顺序排序(默认)
SORT_DESC - 按照下降顺序排序
排序类型标志:
SORT_REGULAR - 将项目按照通常方法比较(默认)
SORT_NUMERIC - 将项目按照数值比较
SORT_STRING - 将项目按照字符串比较

举个栗子:
<?php
	
	/**
    * array_multisort的用法:
    *
    *
    */
    $arr1 = array(
	    '0' => array('a' => 3, 'b' => 20, 'c' => 1, 'd' => 6),
	    '1' => array('a' => 3, 'b' => 2, 'c' => 2, 'd' => 6),
	    '2' => array('a' => 3, 'b' => 22, 'c' => 2, 'd' => 6),
	    '3' => array('a' => 3, 'b' => 25, 'c' => 3, 'd' => 6),
	    '4' => array('a' => 3, 'b' => 28, 'c' => 4, 'd' => 6),
	    '5' => array('a' => 3, 'b' => 30, 'c' => 5, 'd' => 6),
	    '6' => array('a' => 3, 'b' => 28, 'c' => 6, 'd' => 6),
	    '7' => array('a' => 3, 'b' => 34, 'c' => 2, 'd' => 6),
	    '8' => array('a' => 3, 'b' => 35, 'c' => 10, 'd' => 6),
	);
    $arr2 = array(
	    'e1' => array('a' => 3, 'b' => 20, 'c' => 2, 'd' => 6),
	    'e2' => array('a' => 3, 'b' => 2, 'c' => 2, 'd' => 6),
	    'e3' => array('a' => 3, 'b' => 22, 'c' => 2, 'd' => 6),
	    'e4' => array('a' => 3, 'b' => 25, 'c' => 2, 'd' => 6),
	    'e5' => array('a' => 3, 'b' => 28, 'c' => 2, 'd' => 6),
	    'e6' => array('a' => 3, 'b' => 3, 'c' => 2, 'd' => 6),
	    'e7' => array('a' => 3, 'b' => 3, 'c' => 5, 'd' => 6),
	);
	foreach ($arr1 as $key => $value) {
		$tmp[$key] = $value['b'];
		$tmp1[$key] = $value['c'];
	}
	foreach ($arr2 as $key => $value) {
		$tmp2[$key] = $value['b'];
		$tmp3[$key] = $value['c'];
	}
	// array_multisort($tmp,SORT_ASC,$arr1);
	array_multisort($tmp,SORT_DESC,$tmp1,SORT_ASC,$arr1); // 先按照$tmp降序排  在按照$tmp1升序排
	echo "<pre>";
	    print_r($arr1);
	echo "</pre>";
	array_multisort($tmp2,SORT_ASC,$arr2);
	echo "<pre>";
	    print_r($arr2);
	echo "</pre>";
?>


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值