switch 문에서 스위치를 줄이는 방법은 무엇입니까?


9

그래서 데이터베이스에서 두 사람을 기반으로 인사말 줄을 만드는 방법을 만들고 있습니다.

두 개의 이름 ( name1및 name2)과 두 개의 성별 ( gender및 gender2)의 네 가지 매개 변수가 있습니다 .

모든 성별 조합에 대해, 나는 다른 결과를 가지고 있습니다.

예를 들어, 성별 1이 M(man)이고 성별 2도 M이면 출력은 다음과 같아야합니다.

Dear Sir name1 and Sir name2,

현재 내 스위치는 다음과 같습니다.

switch(gender1){
    case 'M':
        switch(gender2){
            case 'M': printf("Dear Sir %s and Sir %s", name1, name2); break;
            case 'W': printf("Dear Sir %s and Madame %s", name1, name2); break;
            case 'R': ...
        }
        break;
    case 'W':
        switch(gender2){
            case 'M': printf("Dear Madame %s and Sir %s", name1, name2); break
            case 'W': printf("Dear Madame %s and Madame %s", name1, name2); break;
            case 'R': ...
        }
        break;
    case ...etc.
}

내가 좋아하는, 여러 성 옵션이 있습니다 'R'에 대한 "Dear Relation"좀 더 내가 번역 할 시간이 없다고합니다.

이 이중 스위치 문을 어떻게 줄일 수 있습니까?

두 번째 스위치를 메소드에 넣는 것은 옵션이 아닙니다. 두 이름이 동일한 경우 출력이 다음과 같이 결합되어야하기 때문입니다. "Dear Sir and Madame name1,"



1
언어에서 허용하는 경우 두 값 이 서로 다른 표현식을 켭니다 ( 예 :) gender1+gender2.
— Kilian Foth

3
관련이없는 점에서 여성의 제목은 여기에 사용 Madam하지 Madame. Madame프랑스 양식입니다.
— rojomoke

3
약간 불필요하지만, '성별'변수가 '남성', '여성'또는 '관계'일 수 있다는 사실은 약간 혼란 스럽습니다.
— Paddy

4
"여러 가지 성별 옵션이 있다는 점에 유의하십시오" 글쎄요, 요즘 유행하고 있습니다.
— 궤도에서 가벼운 경주

답변:


32

printf의 매개 변수에 제목을 추가하십시오.

char* title1;
switch(gender1){
    case 'M':
        title1 = "Sir";
        break;
    case 'W':
       title1 = "Madam";
        break;
    case ...etc.
}
char* title2;
switch(gender2){
    case 'M':
        title2 = "Sir";
        break;
    case 'W':
       title2 = "Madam";
        break;
    case ...etc.
}
printf("Dear %s %s and %s %s", title1, name1, title2, name2);

재사용 성과 컴팩트 성을 위해 스위치를 자체 기능으로 추출 할 수 있습니다.


1
때로는 작동하지 않을 수도 있습니다.
— Deduplicator

4
@Deduplicator 기본적으로 그렇게하고 예외적 인 경우를 별도로 처리하십시오.
— Val

17
… genderToTitle반복 할 필요가없는 기능을 만드 시겠습니까? (또는 루프를 사용하십시오)
— Bergi

18

과격한 해결책 : 사용자가 제공 한 사전 정의 된 목록에서 자신 의 제목을 지정하게하십시오 .

당신의 해결책 (영어 눈으로 볼 때)은 오직 주님 ( "Sir")과 숙녀들을위한 것입니다. 대부분의 남성은 결혼 상태와 개인적 의견에 따라 "Mr", 대부분의 여성은 "Miss", "Mrs"또는 "Ms"로 표시됩니다. 그런 다음 "의사", "교수", "교직자", 심지어 "거룩함"이라는 사이트에 대해 매우 낙관적 인 느낌 이 드는 경우에도 전문적인 순위를 기반으로하는 수많은 다른 명예가 있습니다 !

더 간단한 해결책 : "성별"을 명예롭게 번역하려면 [단일] 기능이 필요합니다. 한 번만 코딩하고 두 사람 모두에게 전화하십시오.

printf("Dear %s %s and %s %s" 
   , getTitle( gender1 ), name1 
   , getTitle( gender2 ), name2 
   ) ; 

여기에 문제가 있습니다 : 나는 데이터베이스를 전혀 제어 할 수 없습니다. 그러나 추가 정보에 감사드립니다. :)
— moffeltje

8
Dear Sir주소 형식으로 모든 남성에게 완벽하게 허용됩니다. 나는 제목 으로 (에서와 같이 Sir Phill) 선생님이 ( 주가 아닌) 기사로 제한되어야 한다는 데 동의 하지만 이는 다른 문제입니다.
— rojomoke

1
이것이 데이터베이스에 액세스하는 방법을 보지 못했습니다. 이것은 나에게 가장 깨끗한 방법입니다. 다른 멋진 스위치 감소가 있지만 이것은 가장 깨끗한 교체이며 논리를 훌륭하게 변조합니다.
— Dan

4
@rojomoke 아니오, 그것은 다른 문제가 아닙니다. 이 질문은 "친애하는 선생님"이 아니라 "친애하는 선생님 (이름 입력)"에 관한 것입니다. "친애하는 선생님 (이름 입력)" 은 "Sir"을 제목으로 사용하고 있습니다.
— hvd

2003 년경 BA 상용 고객 가입 페이지의 제목 드롭 다운 목록에 "거룩함"이있었습니다. 아직도 내가 아는 전부를 위해한다. 드롭 다운이 너무 길어서 통합중인 휴대용 브라우저와 충돌했기 때문에 기억합니다. 나는 특히 그 BA를 제외하고 무료로 필드를 권하고 싶습니다 아마 Debrett의 자문과 (최소한 다른 봉투 주소와 인사말) 다른 컨텍스트에 대한 각 타이틀의 다양한 형태를 알고
— 스티브 Jessop

9

제목은 실제로 데이터베이스에 속하지만 제어 할 권한이 없다고 언급했습니다. 언어 태그를 지정하지 않았지만 구문은 C 제품군에 있으므로 거의 C ++ 인 유사 코드가됩니다.

map<string, string> titles;
titles.emplace("M", "Sir");
titles.emplace("F", "Madam");

cout << "Dear " << titles[gender1] << " " << name1 << " and "
     << titles[gender2] << " " << name2 << endl;

이것의 장점은 선택 논리를 코드 구조가 아닌 데이터 구조에 묻는 것입니다. 이는 데이터베이스에 위임하는 것과 유사하며 더 유연합니다. 맵을 어딘가에 정적 상수로 유지하면 거의 데이터베이스처럼 사용할 수 있습니다 . 더 많은 코드 를 작성할 필요없이 코드의 여러 위치에서 사용할 수있는 단일 구조가 업데이트됩니다 .



C ++ 구문 초기화 (11)와 함께 갈 수있는 좋은 생각, 그리고 그것을 만드는 수 static const: static const map<string, string> titles{make_pair("M", "Sir"), make_pair("F", "Madam")};. 글쎄, const수정이 허용되어야한다면 밖으로 나갈 수 있습니다.
— 중복 제거기

@ 중복 제거기는 확실히 더 좋은 방법이 있습니다. 언어 태그가 없지만 C ++처럼 보입니다 . 그러나 C ++ 11을 가정하면 정확합니다.

3

문장이 모두 같은 패턴이지만 두 개의 삽입이있는 경우 gender1각각에 의존하는 래칫 괴물의 대답 은 꽤 좋은 생각 입니다 gender2.

Phil W.의 답변 은 인사말을 명시 적으로 제어 할 수 있기 때문에 가장 유연한 답변 일 것입니다. 그러나 근본적인 변화는 맞습니다. 해당 형식의 데이터가 없을 수 있습니다.

Kilian Foth의 대답 은 아마도 질문에 대한 최선 의 대답 일 것입니다. 그러나 문자열을 전환하는 데 의존하지만 가능하지 않거나 적어도 더 비쌉니다.

Kilian의 답변을 개선하면 두 입력에서 단일 값을 계산하고 다음을 켜는 것입니다.

// Using a macro in C for readability. C++ would use a constexpr function
#define COMBINE(a, b) ((a<<CHAR_BIT)+b)

switch( COMBINE(gender1, gender2)) {
  case COMBINE('M', 'M'): 
    print "Dear Sirs";
    break;
  case COMBINE('M', 'F'): 
  case COMBINE('F', 'M'): 
    print "Dear Sir and Madam";
    break;
  ...
#undef COMBINE

물론, 데이터베이스에서 4 개의 입력 (2 개의 이름과 2 개의 성별)을 모두 얻을 때 다른 테이블을 추가하고 그에 합류하여 적절한 인사말을 얻는 것이 위의 것보다 더 유연하고 쉬울 것입니다.


2

당신의 언어로 할 수 있다면, 쓸 수 있습니다

switch(gender1+gender2) {
  case "MM": 
    print "Dear Sirs";
    break;
  case "MF": 
  case "FM":
    print "Dear Sir and Madam";
    break;
  ...

여전히 복제가 있기 때문에 반드시 버전보다 낫지 는 않지만 중첩은 피하십시오 switch.


5
이렇게하면 컵케익을 사랑하기 위해 이것을 어레이나 무언가에 넣고 스위치를 제거하십시오 .... salutation [ 'MM'] = "Dear Sirs"; 인사말 [ 'MF'] = "친애하는 부인과 선생님"; 원하는 황산염 = 경례 [성별 1 + 성별 2];
— JDT

1
@JDT 사전 ?
— gnat

전화해야 할 것은 언어에 따라 다르지만 기본적으로 키와 값의 모음입니다.
— JDT

1
거의 모든 언어에서 작동하는 약간의 개선이 있습니다. 두 입력 문자에서 단일 정수를 계산하고 문자열이 아닌 스위치를 켜십시오.
— 중복 제거기

0

지역화 및 업데이트 용이성을 위해 일반적으로 소스 코드에 하드 코딩 된 대신 문자열 테이블에서 이와 같은 UI 문자열을 가져 오기를 원합니다. 그래서 내가 취할 접근법은 입력을 사용하여 조회 키를 작성하는 것입니다.

var lookupKey = "SALUTATION_" + gender1 + "_" + gender2;
var format = GetLocalizedString(lookupKey);
printf(format, name1, name2);

정보를 얻을 수있는 기회가 있다면 사용자가 자신의 타이틀을 선택할 수 있도록하는 다른 제안이 유효합니다. 여전히 솔루션에서 문자열 테이블 조회를 사용합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.