第三十套

1.请实现一个函数,输入一段文本,把文本解析到一个数组中,数组每行元素的key通过输入参数指定。

函数原型:function ExplodeLines($text, $columnNames)
例如,输入:
$text = "
Apple,20,red
Pear,10,yellow
";
$columnNames = array('Fruit', 'Number', 'Color')
函数返回:
array(
array('Fruit'=>'Apple', 'Number'=>'20', 'Color'=>'red'),
    array('Fruit'=>'Pear', 'Number'=>'10', 'Color'=>'yellow'),
)

//答案

function ExplodeLines($text, $columnNames){
    //对text进行处理
    $info=preg_replace('/\n/',';',trim($text));
    //处理好的text分割成数组
    $i=explode(';',$info);
    foreach($i as $key=>$va){
        $i[$key]=explode(',',$va);
        $list[]=array_combine($columnNames,$i[$key]);
    }
    //返回处理好的数组;
    return $list;
}

2.含折扣的退货算法。

函数原型: function CalcRefundAmount($orderItems, $discountAmount, $refundItems)

假设用户有一个订单,
$orderItems = array(
'ItemA'=>array('price'=>5.0, 'quantity'=>2),
'ItemB'=>array('price'=>20.0, 'quantity'=>1),
);
订单中产品ItemA的单价是5.0,数量是2;产品ItemB的单价是20,数量是1;
这个订单总价是 5.0 * 2 + 20.0 * 1 = 30。

假设最终付款的时候,由于这个订单由于使用代金券,优惠了$discountAmount = 10.0 元的价格,用户实际支付了20元。退货的时候,每个产品的退货价格是按照付款折扣率计算的。如果用户退货需要退掉1个ItemA,那么实际退给用户的钱应该是 
(5.0 * 1) * (20.0/30.0) = 3.33 元(精确到2位小数

$refundItems是实际退货的数量。在$orderItems为上述取值,$discountAmount=10的时候
样例1$refundItems = array('ItemA'=>1) 表示退1个ItemA,函数返回3.33
样例2$refundItems = array('ItemA'=>2, 'ItemB'=>1) 表示全退,函数返回20.00

请编写能实现上述功能的函数。

function CalcRefundAmount($orderItems, $discountAmount, $refundItems){
    //是否有优惠
        if($discountAmount){
            echo "本次订单有优惠,优惠额度为:".$discountAmount."
"
; } //此次订单总价为: foreach($orderItems as $key=>$va){ echo "商品".$key."
"
; echo "--商品价格:".$va['price']."
"
."--商品数量:".$va['quantity']."

"
; @$sum+=$va['price']*$va['quantity']."
"
; } //实际付款额 $actualpayment=$sum-$discountAmount; echo "商品总价为:".$sum."
"
; echo "实际支付为:".$actualpayment."
"
; //此次退货清单 foreach($refundItems as $key=>$va){ if(array_key_exists($key,$orderItems)){ echo "你要退的货物为:".$key."退货数量为:".$va."
"
; if($va<=$orderItems[$key]['quantity']){ @$Refundamount+=($orderItems[$key]['price']*$va)*($actualpayment/$sum); }else{ return "你的退货数量与购买量不一样,商品".$key."的购买量为:".@$orderItems[$key]['quantity']."而你的退货数量为:".$va; exit(); } } } return "本次退款金额为:".round(@$Refundamount,2); } //要传递的参数 $orderItems = array( 'ItemA'=>array('price'=>5.0, 'quantity'=>2), 'ItemB'=>array('price'=>20.0, 'quantity'=>1), ); $discountAmount=10; //$refundItems=array('ItemA'=>2); $refundItems = array('ItemA'=>2, 'ItemB'=>1); //函数调用 $list=CalcRefundAmount($orderItems, $discountAmount, $refundItems); echo ($list);

3.抢沙发数据统计。

假设我们有一个文章系统,每个文章都可以被留言。
留言数据保存在 comments 表中。comments表结构如下
字段名 含义
comment_id  留言id(主键)
article_id  被留言的文章的id
uid 写此留言的用户id
nickname    用户昵称
write_time  写留言的时间

抢沙发的定义:
给定一个开始时间 T1,结束时间 T2
如果一个留言是某文章的前5个留言,且留言时间介于T1和T2之间,则认为满足抢沙发条件(另一种等价描述:对于每篇文章的前5个留言中,其中留言时间介于T1和T2之间的留言符合抢沙发条件)。

要求:在给定开始时间T1和结束时间T2的情况下,统计出所有抢沙发成功的用户一共抢到多少个沙发(按抢到沙发的总数逆序排序)。例如:
用户昵称    满足抢沙发的留言总数
小明  32
小刚  25
小红  4
小白  1
小兰  1
编程过程中可以对一些外部条件作出假设(例如假设直接调用mysql查询得到结果),写出主要逻辑即可。
第一步:查询出文章发布时间作为抢沙发的开始时间(时间戳)$T1,并设定有效时间$T2(例如10分钟为600秒,哪么$T2=$T1+600);
第二步:根据文章Id与留言表的article_id做查询,查询出write_time在$T1$T2之间的数据。
    Select nickname as 用户昵称,count(uid) as ‘满足抢沙发的留言总数’ from comments where article_id=1 and  write_time>$T1 and write_time<=$T2 group by uid order by count(uid) desc  limit 5; 

二、设计(选做。高级开发职位必做)
假设我们需要做一个用户金币系统。用户每天第一次登录可以获得1个金币,用户下单购买东西后会获得20个金币。但是这两种金币有不同的性质。对于登录获得的金币(简记为类型A),用户获得之后就可以消费——例如可以用金币买东西。对于下单购买获得的金币(简记为类型B),有一个月的冻结期。在冻结期内类型B的金币不能被消费,如果冻结期内用户发生了退货,则这些类型B的金币会被回收,将来也不让给用户消费。

请设计一个系统(数据库结构和逻辑流程),满足以下要求:
1、用户可以正确的获得上述类型金币
2、用户随时可以知道自己有多少金币可以消费,有多少金币被冻结
3、被冻结的金币在冻结期后成为可以消费的金币
4、用户可以消费自己的可用的金币

只需要设计一种可行方案,描述数据库结构和逻辑算法:
1、发放A金币、发放B金币
2、获取当前有多少可用金币、消费可用金币、获取当前有冻结金币的冻结情况、冻结金币转为可用金币、回收冻结金币

表结构:
用户表:
ID: 标识用户唯一性,自增
Name: 用记名称
A_type: 登录积分
Total: 总积分
logintime登录时间

//如何判断用户是否是第一次登录,并添加相应积分。
    用户每次登录验证成功以后,首先去读取到logintime的时间戳,获取到这个以后,

在程序里用它跟当天的时间戳 todytime(201333000:00:00), logintime小于$todytime,哪就说明本次登录是当天的第一次登录
这个时候执行一次update把用户表里面的A_type的积分+1,并且把logintime的时间戳改为当前时间的时间戳。

积分表:
积分表:用来保存每个用户
ID: 唯一性,自增
Uid: 用于关联用户表
Goodsid 关联商品表
Integral 商品积分
Createtime 购买时间
Endtime 结束时间 // strtotime(” +1 month today”);获得下个月今天的时间戳
State 冻结状态 //0为冻结状态,1为已经状态
Goodstype 标识商品是否被退货 //0为没有,1为退货

B 类积分的获取,以及冻结期过后的积分的处理
    用记每次构买了商品了后将会在商品表里增加一条记录。
    然后,在用户每次登录成功的时候,会查询一次积分表里面的对应用户的数据,如果查询到当前时间戳有大于Endtime的此时表明冻结期已经过了,并且state=0 and goodstype=0的数据,将这些数据的积分汇总后,更新到对应用户表里的total字段里面。并把积分表里面的state状态改为1

用户可通过查询用户表里的A_type+total的总合得到个人的可用总消费积分
通过积分表查询state=0 并且Goodstype=0 的记录并对integral求和,就可以知道该用户的冻结积分为多少了。
用户用金币消费时将会从,用记表里的total表里减去相应积分,如果total金币不够,将会从A_type里面减去不够的金币。

冻结情况:通过查询查分表里面对应用户的积分状态为state=0的endtime 的时间可以获得冻结结束时间。

你可能感兴趣的:(PHP-面试题总集)