几天前遇到这么一个问题:有一个文件记录大量用户的上网记录,要求合并这些信息统计出每个用户的上网时间段。文件中的记录如下:
用户1 开始时间9:15结束时间9:18
用户3 开始时间8:22结束时间8:45
用户1 开始时间9:10结束时间9:16
用户2 开始时间8:31结束时间8:52
用户1 开始时间10:23结束时间10:47
用户1 开始时间9:22结束时间9:38
.......
计算结果是:
用户1 (9:10-18 9:22-9:38 10:23-10:47)
用户2 (8:31-8:52)
用户3 (8:22-8:45)
文件中的记录数据量很大几个亿,用户数量和每个用户的记录都很多,时间是只包含一天中的时间,或许还会要求精确到秒级别,我们以分钟为单位讨论。
解决方案:
按照用户将此问题分解为合并一个用户的上网时间段,每个时间段转化成当天的分钟数(如果精确到秒则转化成当天的秒数)如14:45 是14*60+45=885分钟;或者15:32:21是(15*60+32)*60+21=55941秒。
这样就将问题转化成合并数值段问题最数值为1440-1(精确到分钟)或者86400-1(精确到秒)毫秒类似。这样把问题转化类似成在一个数值范围内的有限数值去重的问题。可以很快想到很多解决方案,用集合,数组,排序等等。
二进制存储结构保存结果:
Java中一个int型数值是32位,我们用一个int数值可以保存32个结果,如时间段是5-27我们将int数值从低5位到27为置1,即使0x07 FF FF F0(0000 0111 1111 1111 1111 1111 1111 0000),因为我们最大值是(86400-1)一个int数值明显不够,可以采用int数组a = int[2700]来保存(一个int可以保存32个结果,86400个只需要2700个int即可)。a[0]记录0-31的结果a[1]记录32-63的结果...依次类推。
数值初始化为0,每处理一个数值段的时候(8776-9844)只需要将数组中对应的位置置1即可如下面的putNum函数,处理完所有数据后,再将结果转化成一个一个时间段就是我们需要的结果如下面的print函数。
int[] a = new int[10000];
public static void putNum(int start,int stop){
int atStart = start>>5;
int begin = start<<27>>>27;
int atStop = stop>>5;
int end = stop<<27>>>27;
for(int i = atStart+1; i < atStop; i++){
a[i] = 0xFFFFFFFF;
}
if(atStart == atStop) {
a[atStart] = a[atStart] | (0xFFFFFFFF << begin & 0xFFFFFFFF >>> 32-end);
} else {
a[atStart] = a[atStart] | (0xFFFFFFFF << begin);
a[atStop] = a[atStop] | (0xFFFFFFFF >>>31-end);
}
}
public static void print(){
boolean currStateIsStart = false;
for(int i = 0; i <a.length; i++){
int num = 1;
for(int j = 0; j < 32; j++){
if((a[i] & num) != 0){
if(!currStateIsStart){
currStateIsStart = true;
System.out.print("开始:" + ((i << 5) + j));
}
} else {
if(currStateIsStart){
currStateIsStart = false;
System.out.println("结束:" + ((i << 5) + j - 1));
}
}
num = num<<1;
}
}
if(currStateIsStart){
System.out.println("最后结束:" + (a.length << 5 - 1));
}
}
相关推荐
- 合并时间段:合并有重叠或相连的时间段。 10. 高级查找 - 给结果集分页:使用ROW_NUMBER()或LIMIT子句进行分页处理。 - 重新生成房间号:根据房间分配逻辑重新编号。 - 跳过表中n行:使用FETCH或LIMIT子句...
4. **数据整合**:如果从多个源或不同时间段导出日志,可能需要合并到一个单一的数据集。这需要解决数据冲突,确保时间序列的一致性,并可能涉及数据去重。 5. **数据分析**:使用统计方法或数据挖掘技术对日志数据...
7. 数据操作:包括字符串操作、日期时间操作、数值运算等。 8. 数据可视化:Pandas可以使用内置绘图功能或者集成Matplotlib、Seaborn等绘图库进行数据可视化。 知识点二:Numpy的使用 1. Numpy数组创建:可以通过np...
同时,MapReduce的分布式计算特性能够充分利用计算资源,提高数据处理的效率,从而大幅度缩短数据处理的时间周期。 综上所述,MapReduce技术在招聘数据清洗方面具有明显的优势,不仅提高了数据处理的效率,还确保了...
通过其可视化的操作界面,用户可以轻松地执行去重、追加、合并、透视、逆透视、数据清洗等多种操作。结合Power Pivot、Power View、Power Map等工具,可以构建复杂的OLAP报表和交互式可视化,进一步提升数据分析的...
37. 全店转化率均值:一段时间内全店转化率的日数据平均值。 38. 促销成交用户数/件数/笔数/金额:参与促销活动的用户数及其对应的交易数量和金额。 39. 非促销成交用户数/件数/笔数/金额:未参与促销活动的用户数...
特征提取部分,报告涉及到解析json字符串以获取嵌套数据,去重确保数据唯一性,将分类数据数字化以便于计算,以及将数据转换为适合分析的类型,如将文本列转化为整型或浮点型。此外,还可能涉及重命名列以提高代码...
在文档中,通过一段JavaScript代码展示了如何判断一个数组中各个数字出现的奇偶次数。具体实现思路如下: - 初始化一个空数组`res`用于存放出现过的数字; - 通过遍历原始数组`arr`,利用`indexOf`方法检查`res`中...
在数据清洗阶段,`pandas`库被广泛用来读取、清洗、转换和合并数据,例如使用`read_csv()`函数加载CSV数据,`dropna()`去除缺失值,`fillna()`填充空值,`groupby()`进行分组统计等。 4. **NumPy**: `numpy`是...
13. 算法的时间复杂度指的是算法执行时间与问题规模的关系,它与数据的存储结构有关。 14. 若要使文本框的初始值为空,需更改`Text`属性。 15. 获取字符串s的最后一个字符,通常使用`s[-1]`。 16. Session和...
6. **小文件合并**:通过设置合理的参数,避免产生过多的小文件。 7. **动态分区**:使用动态分区可以提高数据加载的灵活性。 8. **统计信息收集**:定期收集表的统计信息可以帮助优化器做出更好的决策。 通过上述...
- **推荐方案**:使用`UNION ALL`代替`UNION`,因为`UNION ALL`仅简单地合并两个结果集而不去重,从而提高性能。 #### 二、SQL书写的优化 **1. 同一功能同一性能的不同写法** - **示例**: - A程序员:`SELECT *...
- **销售额随时间变化**:使用`ggplot2`等绘图包绘制销售额随时间的变化趋势,帮助我们直观地理解销售模式。 - **产品类别销售额**:绘制不同产品类别的销售额柱状图,以便快速识别哪些产品类别表现良好。 #### 四...
15. **日期时间类型**:YEAR存储年份,DATE存储日期,TIMESTAMP用于时间(精确到秒),比DATETIME更节省空间。 16. **NULL值**:尽可能定义为NOT NULL,减少数据不一致的可能性。 17. **字段拆分**:对于过大字段...
- **用途**: 在算法分析中用于表示固定的时间或空间复杂度。 #### 36. **前导 0(The Leading Zeroes)** - **定义**: 在数字前面添加的零。 - **用途**: 在字符串格式化或特定编码方案中经常使用。 #### 37. **分配...