• 数组嵌套实现哈希函数的数据分片应用


    什么是哈希算法呢? 哈希算法的定义和原理非常简单,基本上一句话就可以概括了。将任意长度的二进制值串映射为固定长度的二进制值串,这个映射的规则就是哈希算法, 而通过原始数据映射之后得到的二进制值串就是哈希值,简单磊说就是唯一标识的数据映射。

    百度百科中解释为

    Hash,一般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。

    所以也常有人把“散列表”叫作“哈希表 或”Hash表”,把“哈希算法”叫作“Hash算法”或者“散列算法”。

    自编数据标注(分割)软件这个博文中我有提到,需要显示每一帧数据的活动分类结果,考虑到哈希函数可以解决数据分片的问题,所以这里首先选择哈希函数,进行实现,

    首先看一下最终效果图在这里插入图片描述
    可见当我拖动滑动块,选择数据点时,红色箭头指向的活动类型变会随着数据变化而变化。

    数据分片的实现

    哈希函数的实现很简单那就是使用所有的数据点拥有的唯一标识——时间序列,将时间序列映射为从0到n的值。然后为了实现数据分片需要将哈希值映射到不同的区域,在本工程中不同的区域不是固定的,即分割点是变化的,所以根据数据段个数m,新建一个m维动态数组slice,即std::vector<unsigned int> slice,用于存储m个分割点,分割点则以该点的哈希值的形式存储于slice中,同时新建一个m+1维的数组label,即unsigned int label[m+1],用于存储每段数据点的活动标签,这就有一个问题我们如何运用动态数组slice和静态数组label用于标签显示呢?或者说如何将label数组赋值呢。

    实际上我们可以注意到由于我们使用哈希函数,所有数据点的标识都是唯一的,同时也是根据时间序列递增的。实际上在一个嵌套数组labelNum,即unsigned int labelNum[n],便可以解决这进一步的哈希函数。如何嵌套呢,然我们看一下labelNum获取的代码实现。

    void initLabelNum(unsigned int * labelNum, std::vector<unsigned int> slice){
    	initSlice(slice); //slice 获取
    	unsigned int currentNum = 0; //初始化所在段数
    	for(unsigned int i = 0; i < n; i++){
    		if(slice.indexOf(i)!=-1) { // 判断 i 是否在 slice 中
    			currentNum ++ ; //i 在 slice 中 , currentNum ++
    		}
    		labelNum[i] = currentNum;
    	}
    }
    

    可以看出实际上labelNum是记录了第n个元素所在数据段的rank,即是第几段的。那这样我们便可以根据段数去获取该段的标签值。代码实现如下:

    unsigned int getLabel(n){
    	return label[labelNum[n]];
    }
    

    这个问题看似非常简单,但我却花费了挺长时间在这里,总结来说是因为软件的实现需求存在问题,一开始并没有进行整体的分析,只是想着添加分割点后便可以修改数据标签,实际上数组这个数据结构不太适合这样一个动态化的数据,后续我在博文链表的巧妙运用中进行了改进感兴趣的朋友可以关注一下。方法不好,看看就好

    任世事无常,勿忘初心
  • 相关阅读:
    2021.12.10
    2021.12.6
    12月3日
    《大话软件工程需求分析与软件设计》阅读笔记
    《大话软件工程需求分析与软件设计》阅读笔记
    期末加分申请
    2021.12.8
    2021.12.4
    <20211230>主板故障: Win10休眠后黑屏假死,无法回到桌面
    <20211130>怪异的主板故障开机黑屏,不显示, 黄绿灯频闪故障
  • 原文地址:https://www.cnblogs.com/FlameBlog/p/14715378.html
Copyright © 2020-2023  润新知