C 匹配两个数组的有效方法
我有两个数组,一个是输入C 匹配两个数组的有效方法,c,arrays,search,binary-search,C,Arrays,Search,Binary Search,我有两个数组,一个是输入管脚名称,另一个是它们的实际数字 const char *pins[]={"d1","d2","d3","d4","d5","o1","o2","o3","o4"}; const int pinsNumbers[9]={1,2,19,4,14,6,12,15,17}; 当我获取作为输入的“d3”时,我想找到相应的-19 有没有更有效的方法来保存这些“匹配” 如何使用输入在管脚阵列上循环,并尽可能高效地找到匹配的管脚阵列 你可以使用……只要上面的数组被排序。 你可以这样构
管脚名称
,另一个是它们的实际数字
const char *pins[]={"d1","d2","d3","d4","d5","o1","o2","o3","o4"};
const int pinsNumbers[9]={1,2,19,4,14,6,12,15,17};
当我获取作为输入的“d3”时,我想找到相应的-19
你可以使用……只要上面的数组被排序。 你可以这样构造你的数据来模拟C++映射:
struct My_pair {
const char* pin;
int number;
};
const My_pair pairs[] = {
{"d1", 1},
{"d2", 2},
...
};
如果对阵列管脚进行了排序(否则您可以使用例如
qsort
)对其进行排序),则可以使用演示程序中所示的以下方法
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int cmp( const void *a, const void *b )
{
const char *lhs = *( const char ** )a;
const char *rhs = *( const char ** )b;
return strcmp( lhs, rhs );
}
int main( void )
{
const char *pins[] = { "d1", "d2", "d3", "d4", "d5", "o1", "o2", "o3", "o4" };
const int pinsNumbers[] = { 1, 2, 19, 4, 14, 6, 12, 15, 17 };
const char *key = "d3";
const char **p = bsearch( &key, pins, sizeof( pins ) / sizeof( *pins ), sizeof( const char * ), cmp );
if ( p ) printf( "%d\n", pinsNumbers[p - pins] );
return 0;
}
尽可能地简单和快速。如果您将使用两个连续符号(例如
'a'
和'b'
)-您可以计算并检查它,就像下面代码中的组内偏移一样
#包括
#定义D1_VAL 1
#定义D2_VAL 2
#定义D3_VAL 19
#定义D4_VAL 4
#定义D5_VAL 14
#定义D_CNT 5
#定义D_of s 0
#定义O1_VAL 6
#定义O2_VAL 12
#定义O3_VAL 15
#定义O4_VAL 17
#定义O_CNT 4
#定义O_of s D_CNT
#定义管脚数量(D_CNT+O_CNT)
#定义管脚\u GRP\u CNT 2
枚举解码{
解码_OK=0,
解码错误=!解码正确
};
int const引脚编号选项卡[引脚编号]={
D1_VAL,D2_VAL,D3_VAL,D4_VAL,D5_VAL,
O1_VAL,O2_VAL,O3_VAL,O4_VAL,
};
typedef结构{unsigned char chr,ofs,cnt;}pin\u grp\t;
引脚组常数引脚组选项卡[2]={
{.chr='d',.ofs=d_of s,.cnt=d_cnt},
{.chr='o',.ofs=o_of s,.cnt=o_cnt},
};
int pin_到_num(int*num,无符号字符*pin)
{
无符号字符i=0,tmp=pin[1]-0x31;
而(i=pin\u grp\u tab[i].cnt)中断;
*num=pin_num_tab[pin_grp_tab[i].ofs+tmp];
返回DECODE_OK;
}
i++;
}
返回解码错误;
}
内部主(空)
{
int-num;
无符号字符常量inp[]=“d3”;
printf(“\f%s为”,inp);
if(pin到num(&num,inp)=解码确定){
printf(“%d\r\n”,num);
}否则{
printf(“err\r\n”);
}
返回0;
}
比什么更有效的方法?你还没有实现任何东西。保存它的有效方法。我还想知道如何以一种好的方式实现它。使用一个映射而不是两个数组。没有实际的限制,没有“有效的解决方案”。pins
阵列有多长?您多久查询一次pin码?正如@m0skit0所写,您需要一个从字符串到int的映射。通常使用哈希表(O(1)
平均值)或二进制搜索(O(logN)
平均值)来完成。但是如果它是一个很短的数组,您可以简单地遍历pins
数组并找到索引。在示例中它们显然没有排序。@m0skit0:OP可能不关心实际元素的索引,只关心映射。@m0skit0它们在OP的问题中排序,即使它们没有排序,OP可以对它们进行排序。这与其说是一个答案,不如说是一个评论。谢谢,但我不能评论,因为我没有50个声誉:(这仍然是O(N)
@GillBates,但至少数据结构没有OP的那么容易出错。@GillBates可以随意改进:)那么,这与仅仅在两个数组上循环并从一个数组中获取索引以在另一个数组中使用有什么不同呢?@Curnelious这不是更有效,但在您的问题中使用两个数组容易出错。如果您添加了另一个管脚“d6”,则必须将管脚编号添加到pinsNumbers
阵列中的正确位置,否则一切都会混淆。使用struct
解决方案,您只需在对
数组的初始值设定项列表中添加另一个条目,如{“d6”,18}
。
19
#include <stdio.h>
#define D1_VAL 1
#define D2_VAL 2
#define D3_VAL 19
#define D4_VAL 4
#define D5_VAL 14
#define D_CNT 5
#define D_OFS 0
#define O1_VAL 6
#define O2_VAL 12
#define O3_VAL 15
#define O4_VAL 17
#define O_CNT 4
#define O_OFS D_CNT
#define PIN_NUM_CNT (D_CNT+O_CNT)
#define PIN_GRP_CNT 2
enum decode_res_e {
DECODE_OK = 0,
DECODE_ERR = !DECODE_OK
};
int const pin_num_tab[PIN_NUM_CNT] = {
D1_VAL, D2_VAL, D3_VAL, D4_VAL, D5_VAL,
O1_VAL, O2_VAL, O3_VAL, O4_VAL,
};
typedef struct { unsigned char chr, ofs, cnt; } pin_grp_t;
pin_grp_t const pin_grp_tab[2] = {
{ .chr = 'd', .ofs = D_OFS, .cnt = D_CNT },
{ .chr = 'o', .ofs = O_OFS, .cnt = O_CNT },
};
int pin_to_num(int * num, unsigned char * pin)
{
unsigned char i = 0, tmp = pin[1] - 0x31;
while (i < PIN_GRP_CNT) {
if (pin_grp_tab[i].chr == pin[0]) {
if (tmp >= pin_grp_tab[i].cnt) break;
*num = pin_num_tab[pin_grp_tab[i].ofs + tmp];
return DECODE_OK;
}
i++;
}
return DECODE_ERR;
}
int main(void)
{
int num;
unsigned char const inp[] = "d3";
printf("\f%s is ",inp);
if (pin_to_num(&num,inp) == DECODE_OK) {
printf("%d\r\n",num);
} else {
printf("err\r\n");
}
return 0;
}