2013-03-28 1 views
2

이것은 프로그래밍 언어와 관련하여 C입니다.C에서 문자열 연결과 관련된 문제

많은 수의 2D 배열 (sizes are not fixed)이 있습니다. 다음 예제를 고려하십시오.

bool sym_a[][]={{...},{...},...}; //consider these are initialized properly 
bool sym_b[][]={{...},{...},...}; 
... 
bool sym_z[][]={{...},{...},...}; 
bool sym_0[][]={{...},{...},...}; 
bool sym_1[][]={{...},{...},...}; 
... 
bool sym_9[][]={{...},{...},...}; 
... 

모든 이름은 모두 같습니다. 배열 이름의 마지막 문자 만 변경됩니다 (두 개 이상의 문자가 될 수 있지만 중요하지는 않은 경우 더 좋습니다).

이제는 기능이 있습니다. 전달 된 인수에 따라 해당 2D 배열 중 하나를 선택합니다. 그런 다음 선택한 배열로 작업을 수행하십시오. 작업은 일반적인 작업이며 선택한 배열 만 변경됩니다.

예를 들어, 내가 현재 생각할 수있는 것에 따르면 예 스위치 케이스의 경우 아래와 같은 기능을 구현할 수 있습니다.

void doStuff(char letter){ 
    switch(letter){ 
     case 'a': 
      sym_a[0][0]=1; //just for demonstration :D 
     break; 
     case 'b': 
      sym_b[0][0]=1; //same thing, only the character 'a' changed to 'b' 
     break; 
     ... 
     case 'z': 
      sym_z[0][0]=1; 
     break; 
     case '0': 
      sym_0[0][0]=1; 
     break; 
     case '1': 
      sym_1[0][0]=1; 
     break; 
     ... 
     ... 
    }  
} 

그러나 더 좋은 방법이 있어야합니다. 1000 개 배열이 있다면 1000 개를 써야합니까 ?? 모든 경우에 대해 내용은 완전히 동일합니다. 변수 이름의 한 문자 만 변경됩니다.

문자열 연결과 같은 것이 있으면 좋을 것입니다.

#define conc(a,b) a ## b 

그런 다음 conc(sym_,a)sym_a입니다. 하지만 여기서는 직접 적용 할 수 없습니다. 정확한 문자를 conc(a,b)의 오른쪽 인수에 전달할 수 없기 때문에 원하는 문자가 들어있는 변수 만 전달할 수 있습니다.

void doStuff(char letter){ 
    conc(sym_,letter)[0][0]=1; 
} 

conc(sym_,letter)sym_letter을 제공합니다. 하지만 sym_을 문자 변수 letter의 내용과 연결해야합니다.

예를 들어, doStuff('b');으로 전화를 걸면 대신 sym_letter을 입력해야합니다.

희망 사항은 분명합니다. 이 일은 매우 단순 해 보이지만 이것을 제거하는 방법을 생각할 수는 없습니다. 2D 배열의 크기 (행/열 수)는 고정되어 있지 않습니다. 그렇지 않으면 3D 배열을 사용할 수있었습니다.

모든 의견을 환영합니다.

+0

왜 이렇게 많은 2D 변수가 항상 필요합니까? – akshay202

+1

C 언어에는 bool 데이터 형식이 있다고는 생각하지 않습니다. 비트 시프트 연산자를 사용하여 단일 int 배열을 만들고 모든 bool 데이터를 저장할 수 있습니다. – akshay202

+1

@ akshay202 글쎄, 그들은 항상 '살아 있지 않다'(당신은 무엇을 의미 했습니까?). 그것들은 마치 프로그램에 하드 코딩되어 필요할 때만 고려됩니다. 어쨌든 그것은 문제가되지 않습니다. 그러나 당신은 어떤 더 나은 선택권을 보느냐? 그리고 위의 코드는 내가 현재 사용하고있는 것입니다 (예). 하지만 난 간단한 대안이 필요해. – Anubis

답변

1

많은 정적 배열이 있으므로 자연스러운 확장으로 인해 많은 수의 조건문을 사용하게 될 것입니다.

문자 코드를 배열에 매핑하는 추가 정적 배열을 정의 할 수 있습니다.

static const struct { 
    char* lookup_code; 
    bool **array; 
} char_code_lookup[] = { 
    { .lookup_code = "a", sym_a }, 
    { .lookup_code = "b", sym_b }, 
    /* ... */ 
    { .lookup_code = NULL, NULL }, /* Terminator */ 
}; 

귀하의 doStuff 함수는 정적으로 정의 된 배열과 일치하도록 적절한 조회 코드를 찾고 배열을 스캔 할 수 있습니다.

매크로 매직을 사용하면 정적 배열과 정적 조회 배열을 함께 생성하여 중복을 줄일 수 있지만 위에 나열된 방법은 읽기가 쉽습니다.

또는 malloc을 사용하여 동적으로 배열을 할당 할 수 있으며 동시에 런타임에 배열을 만들 때 조회 코드를 연결할 수 있습니다.

+0

정말 '1000'배열 (와이드 문자를 암시 함)이 있다면, 이것은 약간 느릴 수 있습니다. 바이너리 검색을 허용하기 위해'qsort '할 수 있고, (look up 코드의 세부 사항에 따라) 직접 점프를 허용하기 위해 좀 더 재 설계 할 가능성이있다. – Keith

+0

사실, 이와 같은 구현은 느릴 것이다. 표시된 것처럼 일치하는 항목이 발견 될 때까지 각 조회 코드에 대해 'strcmp'가 있습니다. 향상된 디자인은 배열을 동적으로 할당하고 조회 키를 해시 값과 연결하여 O (1) 해시 조회를 허용합니다. –

1

이와 비슷한 것이 있습니까? [사과한다면 여기에 C++가 있습니다. ]

bool** sym_a; 
bool** sym_b ; 
bool** sym_z; 
bool** sym_0; 
bool** sym_1; 
bool** sym_9 ; 


unsigned lowestEntry = 'a'; 
unsigned highestEntry = '9'; 
const unsigned numEntries = highestEntry - lowestEntry; 

size_t size = sizeof(bool**)* numEntries; 

bool*** lookup = (bool***)malloc(size); 

#define conc(a,b) a ## b 
#define index(a) #a[0]-'a' 
#define add(a) lookup[index(a)] = conc(sym_,a) 

void init() 
{ 
    memset(lookup, 0, size); 
    add(a); 
    add(b); 
    add(z); 
    add(9); 
    add(k); // does not compile, sym_k not defined. 
} 

bool** findSymbolTable(char val) 
{ 
    return lookup[val - lowestEntry]; 
} 
1

큰 정수 배열을 할당하고 다른 변수에 대해 분할하십시오.

예 :

int data [2600];

은 sym_a에 대해 처음으로 100 개의 정수를 가지며 sym_b에 대해 100을 갖습니다. 이 배열에 8 * 100 * 4 부울 값을 저장할 수 있습니다. 지금

는 [X] [Y]를 사용하면 총 R 개의 행과 C 열이 말하는 것이다 sym_p 액세스 할 :

INT * 시작 = 데이터 + (ASCIValue (p) - ASCIValue (a)) * 100 ;

당신은 처음부터 비트 번호 (C * x + y)를 읽고 쓸 필요가 있습니다.

관련 문제