zoukankan      html  css  js  c++  java
  • 数组拷贝、数组函数、通过数组函数来模拟数据结构的栈和队列、回调的意义、数组函数的排序问题、算法以及寻找素数的筛选法

    1.数组的拷贝
    数组拷贝时指针的指向问题。

    数组在拷贝时,指针的位置随之复制【这一点拷贝是完全一样】
    但是如果拷贝的数组的指针是非法的,那么拷贝出新指针的位置进行初始化
    <?php
    $arr1=array('123');
    end($arr1);
    next($arr1);//这个指针非法
    $arr2 = $arr1;//这里进行数组的拷贝
    var_dump(current($arr2));//得到指向‘123’元素的指针
    var_dump(current($arr1));//此时这个数组的指针有问题
    ?>


    但是拷贝这个操作本身不能这么说:
    其实质是,拷贝之后,哪个数组先执行current这个操作,哪个数组进行初始化【重点】
    【值传递时,php采用一个cow【copy on write】的机制。值传递时,php其实限时进行一个引用指向,只有两个指向中第一个改变的量会指向一个新创建的值】
    这是php的一个优化思路:并没有马上为新变量开辟值空间,而是先暂时引用之前的量
    <?php
    $arr1=array('123','234');
    end($arr1);
    next($arr1);//这个指针非法
    $arr2 = $arr1;//这里进行数组的拷贝
    var_dump(current($arr1));//得到指向‘123’元素的指针【这里就说明了这个问题】
    var_dump(current($arr2));//此时这个数组的指针有问题
    ?>

    【重点】
    同理:在foreach中,出现对原数组的操作后,因为需要创建一个copy数组【使用的机制也是写时操作cow】
    <?php
    $arr1=array('吕布','赵云','典韦');
    foreach($arr1 as $key=>$value){
    var_dump($key,$value);
    if($key == 2){
    $arr1[] = 'hero';//这个写操作导致了foreach的copy机制
    }
    echo '<br>';
    }
    var_dump(current($arr1));//赵云【因为写操作导致foreach开启copy机制,而copy之后的写操作同样会cow原理,会导致$arr1指针停留在该位置,而foreach遍历的是$arr1的copy数组】
    ?>

    数组指针只要超出期望值,只要对该指针进行一次查找,那么指针便指向第一个元素【指针初始化】

    【重点】
    foreach与指针的问题:
    (1)遍历的是拷贝而不是原数组
    (2)只有在原数组出现写操作之后,才会使用真正的操作。【需要结合foreach的指针移动和指针的变更来考虑数组的指针问题】

    2.数组函数
    结合手册进行数组研究【起码知道有这么个函数,对参数细节不需要太过深究】


    3.通过函数来实现对数据结构的模拟
    模拟栈和队列【对一列数据的处理:栈先进后出(相当于是弹出最后的元素)。队列先进先出(对最前面的元素的处理)】
    push、pop/shift、unshift
    这样便能实现列表的模拟

    入栈和出栈操作之后,会对数组的元素的下标进行重新索引【而使用数组直接添加和删除元素时,下标不会重新索引】
    入栈出栈节省空间,但是效率低


    【函数执行的过程是一个栈的结构:就是后调用的函数要先完成,先调用的函数才能完成】【调用的函数的代码是被编译的代码区域查找已经定义的函数代码】


    4.回调函数
    php使用的情况就是在一个已有函数中调用那些已经定义的函数【被称作回调函数】
    array_map()函数的使用【使用自己定义的函数做回调便可实现】


    5.数组的排序处理
    sort
    按键排序和按值排序
    sort():对数组的元素进行重新排序【默认升序】
    ksort():对键名进行排序【默认升序】【保持键值的关系】
    rsort():对数组元素进行重新排序【降序】
    krsort():对键名进行排序【保持关系,降序】
    asort():按照值进行排序【但是保持键值对关系】
    【关于数组的排序问题,就是只有对值排序才需要考虑键值关系,而对值排序保持关系的是asort()】
    natsort()自然数排序【对计算出的自然数进行排序】【效率低】
    usort()自定义排序【通过使用回调实现自定义排序】

    排序问题,只有需要全局进行排序的时候才会采用数据库进行排序,如果局部排序的问题,采用的还是php进行读取之后,进行排序


    排序算法【重点:结合数据结构和算法进行学习】


    6.实现对一个数是否是素数进行判断【素数就是除了1和本身之外没有任何数能整除该数据(有精简算法)】
    <?php
    function isPrime($n){
    for($d=2;$d<=$n-1;$d++){
    //每一个$d进行整除,这是最复杂的算法。实质上,因为这些循环的数本身有递归的关系,只需要对之前素数进行整除判断即可
    if($n%$d == 0){
    return false;
    }
    }
    return true;//如果不能整除,则为素数
    }
    ?>

    //优化的算法
    (1)首先该数不可能整除它的1/2【因为一个整数不可能除以大于其一般的整数(结果为1.多)】
    (2)对最后整数的数量进行最后的优化【实质上,一个整数查整除的数只需要时当前数的平方根即可(如果平方根都不能整除,那么可以确定是素数)】
    综上:整除算法过程中,整数的除数本身是对应的!!!
    <?php
    function isPrime($n) {
    $sqrt = sqrt($n);
    for($d=2;$d<=$sqrt;$d++){
    if($n%$d==0){
    return false;
    }
    }
    return true;//如果不能整除,则为素数
    }
    ?>


    循环嵌套的问题:
    【continue关键字跳到外层循环的情况】
    循环嵌套中的break的使用【break内层循环】

    7.筛选法【求素数的一个优化算法】
    假设每个数都是素数,从前面第一个(素数)数开始筛选已知的数据范围。【进行整除筛选,一旦被整除,就将其标记为非素数】
    知道筛选到sqrt值

    <?php
    function getPrime($n){
    //首先将数据填充到数组中,做键.元素值为1【做素数标记】array_fill()
    $list = array_fill(2.$n-1,1);
    for($d=2,$sqrt=sqrt($n);$d<=$sqrt;$d++){
    //再进行判断是否为已知素数
    if($list[$d]==1) {
    //进行筛选,从筛选元素的2倍开始筛选【因为小于2倍的数肯定不能整除】
    for($i=$d*2;$i<=$n;$i+=$d){
    //其实质是从2倍$d开始,对$d的整数倍进行查找
    $list[$i]=0;//将整除倍进行置零处理
    }
    }
    }
    //将整个数组中的元素值是1的数据取出【便是素数】
    foreach($list as $key=>$value){
    if($value == 1){
    echo $key.'<br/>';
    }
    }
    }
    ?>
    以上便是实现筛选!!!

    寻找素数的两种算法:
    (1)通过辗转相除【实现循环相除,只是控制最大除数的方法】实现找素数
    (2)筛选法【最大除数已经控制,而且将最大除数内进行标记,进一步减少除数检验次数】

    每个脚本运算使用的执行时间和空间的设置【这一点非常重要,需要结合自己的项目业务】
    【使用空间换时间的逻辑就是这样】


    另外注意isset和empty的区别:
    isset判断变量是否被定义
    empty相当于该值的布尔值的反义词

  • 相关阅读:
    从0系统学Android-2.6Activity间数据传递
    观察者模式详解
    从0系统学Android-2.5更多隐式Intent用法
    从 View 的四个构造方法说起
    ListView详细介绍与使用
    推荐一个程序员系统学习网址
    从 http协议角度解析okhttp
    从0系统学Android-2.4隐式Intent
    菜单布局记录篇
    轮播图记录篇
  • 原文地址:https://www.cnblogs.com/shuoshuren/p/4200164.html
Copyright © 2011-2022 走看看