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