2016-07-28 11 views
2

Ich habe 2 Arrays, eins ist die Eingänge pins names, die andere ist ihre actual numbers.Effiziente Weise, zwei Arrays zu vergleichen

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}; 

Wenn ich als Eingabe "d3" get, würde Ich mag die entsprechenden finden - .

  1. Gibt es eine effizientere Möglichkeit, diese "Übereinstimmungen" zu speichern?
  2. Wie würde man eine Schleife über die Pins Array mit einem Eingang und finden ihre Übereinstimmung so effizient wie möglich?
+3

Ein effizienter Weg als was? Sie haben nichts implementiert. –

+0

effiziente Möglichkeit, es zu speichern. Ich würde auch gerne wissen, wie ich es gut umsetzen kann. – Curnelious

+4

Verwenden Sie eine Karte anstelle von 2 Arrays. – m0skit0

Antwort

1

Sie können eine binary search ... verwenden, solange das obige Array sortiert ist.

+0

Sie sind im Beispiel offensichtlich nicht sortiert. – m0skit0

+0

@ m0skit0: OP interessiert sich wahrscheinlich nicht für den Index des eigentlichen Elements, sondern nur für das Mapping. – Groo

+0

@ m0skit0 sie sind in der OP-Frage sortiert und selbst wenn sie nicht wären, könnte das OP sie sortieren. –

3

Sie können Ihre Daten wie diese Struktur eine C++ Karte zu emulieren:

struct My_pair { 
    const char* pin; 
    int number; 
}; 

const My_pair pairs[] = { 
    {"d1", 1}, 
    {"d2", 2}, 
    ... 
}; 
+0

Dies ist immer noch 'O (N)'. –

+1

@GillBates aber zumindest die Datenstruktur ist weniger fehleranfällig als die OP's. –

+0

@MichaelWalz Fair Punkt, aber OP fragte nach einem effizienten Weg. –

4

Wenn die Array-Stifte bestellt wird (sonst kann man es zum Beispiel sortieren mit qsort), dann können Sie den folgenden Ansatz, wie es verwenden gezeigt, ist in dem Programm demonstrativen

#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; 
} 

die Programmausgabe ist

19 
2

So einfach und schnell wie es geht. Und wenn Sie zwei aufeinanderfolgende Symbole verwenden (zum Beispiel 'a' und 'b') - können Sie es berechnen und als Offset innerhalb von Gruppen im folgenden Code überprüfen. Ideone online executable code.

#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; 
} 
Verwandte Themen