热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PHP面试任务:一周计算

不久前,有人给了我一个面试的任务。我是写一个函数,推导出的标准一周工作七天的任何日历(甚至一个虚构的),提供我知道闰年发生频率,如果有的话,一年有多少个月,每个月有多少天。

不久前,有人给了我一个面试的任务。我是写一个函数,推导出的标准一周工作七天的任何日历(甚至一个虚构的),提供我知道闰年发生频率,如果有的话,一年有多少个月,每个月有多少天。

这是一个相当常见的介绍性job-interview任务,在本文中我将解决和解释其背后的数学。我没有电影那么随意扔简化和修正我——我相信我是一个不必要的复杂的。本文将呈现接近问题的两个方面——一个可以让你精神这么做动态(给你的朋友留下深刻印象,我猜?),和一个电脑更友好(更少的代码行,更多)。

日历的定义我得到了如下:

  • 每年有13个月
  • 甚至每一个月21天,每个奇怪的月有22
  • 13月缺少一天每个闰年
  • 闰年是任何被5整除
  • 每周7天:星期天,星期一,星期二,星期三,星期四,星期五,星期六

任务如下:

考虑到1900年的第一天是星期一,编写一个函数,将打印给定日期的星期。的例子中,输入{:17日月:11日:2013 }输出“星期六”。

在本文的其余部分,我将使用以下日期格式:dd.mm。yyyy,因为它是什么是有意义的.

准备

在开始任何聪明的风险之前,有一个适当的环境设置是很重要的,以避免浪费时间在那些可能是提前准备。我总是建议你进入编码面试任务跃跃欲试的开发环境,可以测试您的代码在片刻的注意。

创建一个新文件夹包含两个子文件夹: classes, public。是的,这是一个一次性的任务,它可以解决一个简单的程序功能,但我喜欢彻底。你就会明白为什么。

在 classes子文件夹,创建一个空的PHP类 CalendarCalc.php。在 public子文件夹,创建一个文件 index.php用下面的内容:


如果你可以在浏览器中打开这个显示“Hello”,您已经准备好开始。

CalendarCalc初始化

使事情更容易验证和想象,我创建了一个演示方法从1.1.1900打印出整个日历。22.13.2013。这将使我们能够轻松地检查我们的计算功能。不过,首先初始化类一样:

iNumDays = count($this->aDays);
        $this->iStartDayIndex = array_search('Monday', $this->aDays);
        $this->aInput = array('d' => $day, 'm' => $month, 'y' => $year);
    }

    public function demo() {
    }
}

让我们解释受保护的属性。

$aDays是一个数组。定义它确保每个星期有数字索引分配——至关重要的在确定星期后的一天。我们缓存它的长度 $iNumDays财产。这让我们扩展数组在以后的日子里,如果我们选择——另一个任务可能会问同样的计算,但提到本周可能已经或多或少地超过7天。

$iStartDayIndex是周一的索引(在本例中),因为一开始天周一(1.1.1900)被定义为在任务描述。当我们开始一天的索引,我们可以用它与计算抵消得到真正的星期。你会明白我的意思。

$aInput是一个数组来保存输入值。当我们实例化CalendarCalc,我们通过的日期值我们想知道本周的日子。这个属性存储这些值,可供我们每想出calc方法,从而确保我们不需要它们,或者更糟的是,重复它们在另一个函数调用。的逻辑 $aInput, $iStartDayIndex和 $iNumDays是在 __construct方法。

其他属性都是不言而喻的。

现在,填充 demo()方法用下面的内容:

public function demo() {

        $demoYear = $this->startYear;
        $totalDays = 0;

        while ($demoYear <2014) {

            echo "

$demoYear

"; $demoMOnth= 1; while ($demoMonth <14) { echo ""; echo ""; $dayCount = ($demoMonth % 2 == 1) ? 22 : 21; $dayCount = ($demoMOnth== 13 && $demoYear % 5 == 0) ? 21 : $dayCount; $demoDay = 1; echo ""; while ($demoDay <= $dayCount) { $index = ++$totalDays % 7; if ($demoDay == 1) { for ($i = 0; $i <$index-1; $i++) { echo ""; } if ($index == 0 || $index == 7) { $i = 6; while ($i--) { echo ""; } } } echo ""; if ($index == 0) { echo ""; } $demoDay++; } echo ""; $demoMonth++; } echo "
Month $demoMonth
MondayTuesdayWednesdayThursdayFridaySaturdaySunday
$demoDay

"; $demoYear++; } }

别烦试图理解这种方法——它是完全不重要。这只是帮助我们验证工作,并根据第二个解决方案实际上是部分我们将在本文中呈现。

改变的内容索引。php文件:

demo();

…并在浏览器中打开它。您应该看到一个日历输出与一下图:

我们现在有一种检查结果17.11.2013真理(注意日期。确实是周六)。

精神的方式

心理的方法计算其实很简单。首先,我们需要的数量闰年日期之间的基地,和给定日期。1900是被5整除,本身就是一个闰年。跳跃的数量因此年之间的差异日期输入日期和基地,除以5,四舍五入(只有充分运行年统计,自然),1900年加一。创建一个新的方法 CalendarCalc被称为 calcFuture并给它这个内容:

$iLeaps = floor(($this->aInput['y'] - $this->startYear) / $this->leapInterval + 1);

我们甚至还被告知,每个月有21天,和每一个奇怪的月有22:

1 = > 22
2 = > 21
3 = > 22
4 = > 21
5 = > 22
6 = > 21
7 = > 22
8 = > 21
9 = > 22
10 = > 21
11 = > 22
12 = > 21
13 = > 22(或21日在闰年)

总天数在一年,因此,280年,或者279年在闰年。如果我们的模7 280%,0,因为280年是被7整除。在闰年,模是6。

这意味着每年的日历在同一天开始,除了闰年,当它开始那天,在前一年的第一天。因此,如果1.1.1900。周一:

  • 1.1.1901。是星期一
  • 1.1.1902。是星期天
  • 1.1.1903。是星期天
  • 1.1.1904。是星期天
  • 1.1.1905。是星期六
  • 1.1.1906。是星期六
  • 等…

根据这一点,我们可以计算的数量一天行动,直到我们的输入。看到我们知道我们有23跳跃,直到输入日期(2013),我们搬回一天23倍。23%的模7是2,这意味着我们总算圆满3次,然后两天(这是抵消)——1.1.2013。是星期六。检查演示日历,看看自己。

让我们先来了解代码。“飞跃”线以上,后添加以下:

$iOffsetFromCurrent = $iLeaps % $this->iNumDays;

        $iNewIndex = $this->iStartDayIndex - $iOffsetFromCurrent;

        if ($iNewIndex <0) {
            $iFirstDayInputYearIndex = $this->iStartDayIndex + $this->iNumDays - $iOffsetFromCurrent;
        } else {
            $iFirstDayInputYearIndex = $iNewIndex;
        }

首先,我们计算偏移量。然后,我们计算日子的新索引数组,它取决于是否新指数是积极的。这给了我们一周的日子我们输入年开始。

我们也知道,每个月X与下个月21天使当日月开始X,因为21% 7 = 0。然而奇怪的几个月里,开始提前一天(22% 7 = 1)。因此,如果1月从星期六开始,2月从周日开始,周日3月,4月,星期一,等等。我们得出这样的结论:每一个奇怪的月,通过了今年年初以来直到我们输入日期1月一天拥有先进的指数。我们在11月,所以奇怪有5个月。新抵消+ 5或在我们的案例中,2013年11月,周四开始。让我们把它变成代码立即在前面行。

$iOddMOnthsPassed= floor($this->aInput['m'] / 2);

$iFirstDayInputMOnthIndex= ($iFirstDayInputYearIndex + $iOddMonthsPassed) % $this->iNumDays;

现在剩下的就是看看远离本月初我们输入日期的一天。

$iTargetIndex = ($iFirstDayInputMonthIndex + $this->aInput['d']-1) % $this->iNumDays;

return $this->aDays[$iTargetIndex];

我们添加减一天(因为天还没有通过!),模7日的天数。我们得到的数量是我们的目标指数,可靠地给我们星期六。

从现在,整个 calcFuture的方法 CalendarCalc是这样的:

/**
     * A more "mental" way of calculating the day of the week
     * @return mixed
     */
    public function calcFuture() {
        $iLeaps = floor(($this->aInput['y'] - $this->startYear) / $this->leapInterval + 1);
        $iOffsetFromCurrent = $iLeaps % $this->iNumDays;

        $iNewIndex = $this->iStartDayIndex - $iOffsetFromCurrent;

        if ($iNewIndex <0) {
            $iFirstDayInputYearIndex = $this->iStartDayIndex + $this->iNumDays - $iOffsetFromCurrent;
        } else {
            $iFirstDayInputYearIndex = $iNewIndex;
        }

        $iOddMOnthsPassed= floor($this->aInput['m'] / 2);

        $iFirstDayInputMOnthIndex= ($iFirstDayInputYearIndex + $iOddMonthsPassed) % $this->iNumDays;

        $iTargetIndex = ($iFirstDayInputMonthIndex + $this->aInput['d']-1) % $this->iNumDays;

        return $this->aDays[$iTargetIndex];
    }

machine-friendly方式

也许更简单的方法是计算的天数,已基本日期、模,7和得到抵消。没有很多人可以计算数字的大小,不过,这就是为什么它更machine-friendly。

再一次,我们需要跳跃:

public function calcFuture2() {
    $iTotalDays = 0;

    $iLeaps = floor(($this->aInput['y'] - $this->startYear) /    $this->leapInterval + 1);
}

然后,考虑到年。经过数年的280次,减去的跳跃数占了天,加一,因为今年仍在进行中。

$iTotalDays = (280 * ($this->aInput['y'] - $this->startYear)) - $iLeaps + 1;

然后,我们添加在总结所有的运行。

$iTotalDays += floor($this->aInput['m'] / 2) * 21 + floor($this->aInput['m'] / 2) * 22;

最后,我们添加输入日期的日子,再减去一天因为当前尚未通过:

$iTotalDays += $this->aInput['d'] - 1;
        return $this->aDays[$iTotalDays % $this->iNumDays];

死很简单,不是吗?

结论

看到一个生活例子计算,请检查在这里。你可以浏览目录包含在该URL查看文件,或者您可以下载完整的源代码,演示网站,以及最后的 CalendarCalc类,从GitHub。回购/演示稍微比本文中提供的代码——一些html5boilerplate用于更有组织性和启用ajax请求来检查您输入的日期作为他们,所以你不需要重新加载屏幕和再生日历每次检查日期。

如果你有改进的替代方案或建议,请在下面的评论中让他们-就像我说的我没有数学奇才,欢迎有机会学习更多的知识。例如,一个人应该考虑角情况下,边缘日期,或日期在过去需要更多的修改原来的算法。我将这些留给你。随时提交拉请求,你会得到一个喊出这篇文章!

希望你喜欢这和学习新东西!祝你好运在你的采访!


推荐阅读
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • PHP玩家基地系统毕业设计(附源码、运行环境)的用户登录界面、游戏管理和玩家作品管理
    本文介绍了一个PHP玩家基地系统的毕业设计,包括用户登录界面、游戏管理和玩家作品管理等功能。附带源码和运行环境,并提供免费赠送本源代码和数据库的方式,请私信获取详细信息。摘要共计约XXX字。 ... [详细]
  • 本文描述了作者第一次参加比赛的经历和感受。作者是小学六年级时参加比赛的唯一选手,感到有些紧张。在比赛期间,作者与学长学姐一起用餐,在比赛题目中遇到了一些困难,但最终成功解决。作者还尝试了一款游戏,在回程的路上感到晕车。最终,作者以110分的成绩取得了省一会的资格,并坚定了继续学习的决心。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • 关羽败走麦城时路过马超封地 马超为何没有出手救人
    对当年关羽败走麦城,恰好路过马超的封地,为啥马超不救他?很感兴趣的小伙伴们,趣历史小编带来详细的文章供大家参考。说到英雄好汉,便要提到一本名著了,没错,那就是《三国演义》。书中虽 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • PHP设置MySQL字符集的方法及使用mysqli_set_charset函数
    本文介绍了PHP设置MySQL字符集的方法,详细介绍了使用mysqli_set_charset函数来规定与数据库服务器进行数据传送时要使用的字符集。通过示例代码演示了如何设置默认客户端字符集。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 橱窗设计的表现手法及其应用
    本文介绍了橱窗设计的表现手法,包括直接展示、寓意与联想、夸张与幽默等。通过对商品的折、拉、叠、挂、堆等陈列技巧,橱窗设计能够充分展现商品的形态、质地、色彩、样式等特性。同时,寓意与联想可以通过象形形式或抽象几何道具来唤起消费者的联想与共鸣,创造出强烈的时代气息和视觉空间。合理的夸张和贴切的幽默能够明显夸大商品的美的因素,给人以新颖奇特的心理感受,引起人们的笑声和思考。通过这些表现手法,橱窗设计能够有效地传达商品的个性内涵,吸引消费者的注意力。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • faceu激萌变老特效的使用方法详解
    本文介绍了faceu激萌变老特效的使用方法,包括打开faceu激萌app、点击贴纸、选择热门贴纸中的变老特效,然后对准人脸进行拍摄,即可给照片添加变老特效。操作简单,适合新用户使用。 ... [详细]
author-avatar
懒得张开眼睛看你
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有