如何查找两个数组表

为什么要写这篇

算是一次更深一些的思考吧,对于查数据表,通常都只有一个表格,如果翻看数据手册,就会看到数据表中对应的数值只是一个典型值,而实际情况是传感器的值必定会在某个范围内波动,对应一个上限值和一个下限值。通常使用这个典型值就可以了,方法就是这篇博客:

但如果需要查找两个数据表,分别是上限表和下限表,那该怎么办呢?顺序查表?有没有可能落空呢?我想到一个比较简单的办法,只要在范围内,必定会返回一个数值。

怎么实现

先对ADC采集的数值分别在两个数据表中进行查找,得到两个相近的值(假设是温度),然后再进一步判断(判断是否在该温度的上下限中,若不在两个温度的上下限中,则找最接近的温度),得到最接近的值(温度)。前提是传感器的上下限不存在重合部分,传感器的数值对应唯一温度

程序如下,可直接复制到菜鸟C在线工具中运行

#include <stdio.h>
#include <stdint.h>

#include <stdlib.h>
#include <time.h>

#define DEBUG_OUTPUT	0
#define ARRAY_SIZE 		40

uint16_t lower_limit[40] =
{
    6132,    5988,    5842,    5697,    5553,    5411,    5269,    5129,    4991,    4855,  
    4720,    4588,    4457,    4329,    4203,    4079,    3958,    3839,    3722,    3608,
    3497,    3388,    3282,    3178,    3077,    2977,    2881,    2786,    2694,    2604,
    2517,    2432,    2350,    2270,    2193,    2119,    2047,    1976,    1909,    1843
};


uint16_t higher_limit[40] = 
{
    6261,    6115,    5966,    5818,    5671,    5525,    5380,    5237,    5095,    4955,
    4817,    4681,    4547,    4415,    4285,    4158,    4033,    3910,    3790,    3673,
    3558,    3446,    3336,    3229,    3125,    3022,    2927,    2833,    2741,    2652,
    2565,    2481,    2400,    2320,    2243,    2169,    2097,    2027,    1959,    1894
};

uint16_t search_based_on_dichotomy(uint16_t key, const uint16_t *a, uint16_t n);

int main(void)
{
	srand((unsigned)time(NULL));
	
	for(uint8_t i=0; i<5; i++)
	{
		uint16_t random_val = rand() % 4400 + 1845;
		printf("random_val is %d \n", random_val);
		uint8_t return_val1 = search_based_on_dichotomy(random_val, lower_limit, sizeof(lower_limit)/sizeof(lower_limit[0]));
		uint8_t return_val2 = search_based_on_dichotomy(random_val, higher_limit, sizeof(higher_limit)/sizeof(higher_limit[0]));
		
		if((higher_limit[return_val1] > random_val) && (random_val > lower_limit[return_val1]))
		{
			printf("AA the need value is %d \n\n", return_val1);
		}else if((higher_limit[return_val2] > random_val) && (random_val > lower_limit[return_val2]))
		{
			printf("BB the need value is %d \n\n", return_val2);
		}else 
		{
			if((higher_limit[return_val1] - random_val) < (random_val - lower_limit[return_val2]))
			{
				printf("CC the need value is %d \n\n", return_val1);
			}else
			{
				printf("DD the need value is %d \n\n", return_val2);
			}
			
		}
		
	}
	
	
    return 0;
}



/**

 * @brief   基于二分查找法,需要数组是递减序列

 * @param	key 要查找的值

 * @param	a  数组元素首地址

 * @param	n  数组元素个数

 * @note	对传入参数进行验证

 * @note 	不是数组元素也会查找成功,关键是如何判断介于两者之间,终止条件已做更改

 * @note    若到两数的间隔相等,则会返回较小的数

 * @attention 此处要求数组元素个数2^8 =256应用限制较多,因此改为uint16_t

 */

uint16_t 
search_based_on_dichotomy(uint16_t key, const uint16_t *a, uint16_t n)    ///< 传入类型更改
{   
    uint16_t low, high, mid;
	uint8_t count=0;
	
    low = 0;
    high = n; 

    if((key > a[0]) || (key < a[ARRAY_SIZE - 1]))      //传入参数验证  ///< 递减序列更改             
    {
#if DEBUG_OUTPUT
        printf("The key is not in array range \n");
#endif
        return 0;
    }     

    while(low < high)
    {
        count++;        //记录查找次数
#if DEBUG_OUTPUT
		printf("\n search times : %d \n", count);
#endif
        mid = (low + high) / 2;
		if(key == a[mid])
		{
			return mid;
		}else if(key > a[mid])          ///< 递减序列更改
        {
#if DEBUG_OUTPUT
            printf("key > array[mid]  high = %d, mid = %d, low = %d \n", high, mid, low);
            printf("array[high] = %d,  array[mid] = %d,  array[low] = %d \n",  a[high], a[mid], a[low]);
#endif
			if(key > a[mid - 1])        ///< 递减序列更改
			{
				high = mid - 1;
			}else
            {
                if(abs(key - a[mid - 1]) < abs(a[mid] - key))           
                {
#if DEBUG_OUTPUT
                    printf(" the closer value is array[mid - 1] = %d \n", a[mid - 1]);
#endif
                    return mid - 1;
                }else
                {
#if DEBUG_OUTPUT
                    printf(" the closer value is array[mid] = %d \n", a[mid]);
#endif
                    return mid;
                }
            }
        }else if(key < a[mid])          ///< 递减序列更改
        {
#if DEBUG_OUTPUT
            printf("key < array[mid]  high = %d, mid = %d, low = %d \n", high, mid, low);
            printf("array[high] = %d,  array[mid] = %d,  array[low] = %d \n",  a[high], a[mid], a[low]);
#endif

			if(key < a[mid + 1])        ///< 递减序列更改
			{
				low = mid + 1;
			}else
            {
                if(abs(a[mid + 1] - key) > abs(key - a[mid]))          
                {
#if DEBUG_OUTPUT
                    printf(" the closer value is array[mid] = %d \n", a[mid]);
#endif
                    return mid;
                }else
                {
#if DEBUG_OUTPUT         
					printf(" the closer value is array[mid + 1] = %d \n", a[mid + 1]);
#endif
                    return mid + 1;
                }
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/quanquanxiaobu/article/details/112172655
今日推荐