摘要:于是,我寫了下面的函數(shù)檢查格式,必須是位僅含的字符串找出對應(yīng)的位置,通過,最終余留的元素就是已選中的幾個(gè)值,非選中元素被剔除了如果所有的時(shí)段都沒有被訂利用剩下的這個(gè)進(jìn)行字符串處理用兩個(gè)遍歷,解決了這個(gè)問題。
最近跟二進(jìn)制字符串杠上了,總是喜歡對二進(jìn)制字符串存儲和運(yùn)算進(jìn)行研究。今天又來寫一個(gè)使用場景的代碼。
使用場景:在項(xiàng)目中需要存儲一個(gè)對象被租用的時(shí)間段,以每個(gè)小時(shí)作為一個(gè)時(shí)間段,從8:00到晚上20:00,一共12個(gè)時(shí)間段;現(xiàn)在按照二進(jìn)制字符串的形式存儲每個(gè)時(shí)間段被租用的情況,如果該時(shí)段被租用,就在對應(yīng)的位置上用1表示,未租用就用0表示,例如 001100000100 表示10:00-12:00,17:00-18:00這兩個(gè)時(shí)間段被租用,并將該二進(jìn)制字符串存儲在數(shù)據(jù)庫中;現(xiàn)在,在讀取數(shù)據(jù)時(shí),需要將二進(jìn)制字符串還原為時(shí)間段,(如果出現(xiàn)連續(xù)的時(shí)間段時(shí),需合并為一個(gè)跨多個(gè)小時(shí)的時(shí)間段),寫一個(gè)函數(shù)來實(shí)現(xiàn)。
在面對這個(gè)問題的時(shí)候,我想了很多,因?yàn)槲覀円獜谋憬菪院托蕛蓚€(gè)角度去思考,如果僅僅是為了實(shí)現(xiàn)便捷性,那么通過拆分?jǐn)?shù)組,遍歷,一定能很快實(shí)現(xiàn)。于是,我寫了下面的函數(shù):
function bin_string_to_hours($string,$hours = array("08:00-09:00","09:00-10:00","10:00-11:00","11:00-12:00","12:00-13:00","13:00-14:00","14:00-15:00","15:00-16:00","16:00-17:00","17:00-18:00","18:00-19:00","19:00-20:00")) { // 檢查$string格式,必須是12位僅含01的字符串 if(!preg_match("/^[0|1]{12}$/",$string)) return false; // 找出對應(yīng)的位置,通過unset,最終余留的$hours元素就是已選中的幾個(gè)值,非選中元素被剔除了 $arr = str_split($string); foreach($arr as $key => $value) { if($value == 0) unset($hours[$key]); } // 如果所有的時(shí)段都沒有被訂 if(empty($hours)) return null; // 利用剩下的這個(gè)$hours進(jìn)行字符串處理 $hours = array_values($hours); $result = array(); list($start, $last) = explode("-", $hours[0]); for($i = 1, $n = count($hours); $i < $n; $i++) { list($start2, $last2) = explode("-", $hours[$i]); if ($start2 != $last) { $result[] = $start . "-" . $last; $start = $start2; $last = $last2; } else { $last = $last2; } } $result[] = $start . "-" . $last; unset($hours); return implode(",", $result); }
用兩個(gè)遍歷,解決了這個(gè)問題。但是,有沒有更燒腦的解決辦法呢?我又做了下面的修改。
function bin_string_to_hours($string,$hours = array("08:00-09:00","09:00-10:00","10:00-11:00","11:00-12:00","12:00-13:00","13:00-14:00","14:00-15:00","15:00-16:00","16:00-17:00","17:00-18:00","18:00-19:00","19:00-20:00")) { // 檢查$string格式,必須是12位僅含01的字符串 if(!preg_match("/^[0|1]{12}$/",$string)) return false; // 通過對字符串進(jìn)行數(shù)組切割,然后通過循環(huán)遍歷,找出所有1,并將連續(xù)的(或單個(gè)的)1分為一個(gè)組 $i = 0; $groups = array(); $arr = str_split($string); foreach($arr as $key => $value) { if(isset($arr[$key - 1]) && $arr[$key - 1] == $value) // 如果上一個(gè)元素與當(dāng)前元素相等(同為1或0),不進(jìn)行任何操作 {} else // 如果當(dāng)前元素與上一個(gè)元素不同(一個(gè)為0,一個(gè)為1),那么新建一個(gè)組 { $i ++; } if($value == 0) // 如果該值為0,這個(gè)組別就沒有存在的必要了 { unset($groups[$i]); continue; } $groups[$i][] = $key; // 把對應(yīng)的索引存入到組中 } // 從分組中取出對應(yīng)的索引,在按每組去對字符串進(jìn)行處理:該組的第一個(gè)索引對應(yīng)的字串的前面部分,和最后一個(gè)索引對應(yīng)的字串的后面部分,就是時(shí)間的開始與截止 $return = array(); foreach($groups as $group) { $index_start = current($group); if(count($group) == 1) // 如果這個(gè)組只有一個(gè)元素,也就是只有一個(gè)時(shí)間段,直接返回這個(gè)時(shí)間段的值即可 { $return[] = $hours[$index_start]; continue; } $index_end = end($group); $string_start = current(explode("-",$hours[$index_start])); $string_end = end(explode("-",$hours[$index_end])); $return[] = $string_start."-".$string_end; } $return = implode("-",$return); return $return; }
通過分組構(gòu)建分組數(shù)組的方法來解決,如果數(shù)據(jù)量大的時(shí)候,明顯這種方法更加節(jié)省資源。可是,當(dāng)我和小伙伴兒再繼續(xù)燒腦的時(shí)候,在馬上把腦袋烤熟的一瞬間,我們發(fā)現(xiàn)了只需要一次遍歷就可以解決問題的辦法。
function bin_string_to_hours($string,$hours = array("08:00","09:00","10:00","11:00","12:00","13:00","14:00","15:00","16:00","17:00","18:00","19:00","20:00")) { if(!preg_match("/^[0|1]{12}$/",$string)) return false; // 檢查$string格式,必須是12位僅含01的字符串 $result = array(); $index_start = 0; // 用來記錄連續(xù)的1最前的索引 $index_end = 0; // 用來記錄連續(xù)的1最末的索引 $count = 0; // 用來記錄有多少個(gè)連續(xù)的1 for($i = 0; $i <= 12; $i ++) { if($i < 12 && $string[$i] == "1") // string最大索引為11,所以這里必須<12 { if($count == 0) $index_start = $i; $index_end = $i + 1; $count ++; } else { if($count > 0 && $index_end - $index_start == $count) // count必須>0的情況下,在能進(jìn)行字符串組合,為0就沒有意義了 $result[] = $hours[$index_start]."~".$hours[$index_end]; $count = 0; } } return implode(",",$result); }
這個(gè)算法里面,把上面原本用時(shí)間段作為元素的$hours,改成了把每個(gè)小時(shí)時(shí)間點(diǎn)作為元素,很快,一個(gè)循環(huán)就把我們的目標(biāo)效果實(shí)現(xiàn)了。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/21088.html
摘要:本章將介紹基本的數(shù)據(jù)結(jié)構(gòu)。松鼠人一般在晚上八點(diǎn)到十點(diǎn)之間,雅克就會變身成為一只毛茸茸的松鼠,尾巴上的毛十分濃密。我們將雅克的日記表示為對象數(shù)組。 來源:ApacheCN『JavaScript 編程精解 中文第三版』翻譯項(xiàng)目原文:Data Structures: Objects and Arrays 譯者:飛龍 協(xié)議:CC BY-NC-SA 4.0 自豪地采用谷歌翻譯 部分參考了《Jav...
摘要:說到檔案系統(tǒng),選文檔數(shù)據(jù)庫再合適不過了。熟悉的人看這個(gè)會很眼熟,沒錯,這就是從借鑒過來,并用在我的關(guān)系數(shù)據(jù)庫查詢上。接口規(guī)范接口的主要目是為了傳遞數(shù)據(jù),數(shù)據(jù)結(jié)構(gòu)已經(jīng)在上面給出。為便于不同系統(tǒng)不同終端的數(shù)據(jù)交換,也將應(yīng)當(dāng)在接口支持之內(nèi)。 說到檔案系統(tǒng),選文檔數(shù)據(jù)庫再合適不過了。談到文檔數(shù)據(jù)庫一般想到的是 MongoDB、CouchDB 之類的,可這里要說的不是這些,而是另一個(gè) NoSQL...
摘要:說到檔案系統(tǒng),選文檔數(shù)據(jù)庫再合適不過了。熟悉的人看這個(gè)會很眼熟,沒錯,這就是從借鑒過來,并用在我的關(guān)系數(shù)據(jù)庫查詢上。接口規(guī)范接口的主要目是為了傳遞數(shù)據(jù),數(shù)據(jù)結(jié)構(gòu)已經(jīng)在上面給出。為便于不同系統(tǒng)不同終端的數(shù)據(jù)交換,也將應(yīng)當(dāng)在接口支持之內(nèi)。 說到檔案系統(tǒng),選文檔數(shù)據(jù)庫再合適不過了。談到文檔數(shù)據(jù)庫一般想到的是 MongoDB、CouchDB 之類的,可這里要說的不是這些,而是另一個(gè) NoSQL...
閱讀 881·2023-04-25 19:17
閱讀 2179·2021-09-10 11:26
閱讀 1898·2019-08-30 15:54
閱讀 3411·2019-08-30 15:53
閱讀 2681·2019-08-30 11:20
閱讀 3391·2019-08-29 15:12
閱讀 1229·2019-08-29 13:16
閱讀 2384·2019-08-26 12:19