จะลดสวิตช์ในคำสั่ง switch ได้อย่างไร?


9

ดังนั้นฉันจึงสร้างวิธีการสร้างบรรทัดคำทักทายตามคนสองคนจากฐานข้อมูล

มีพารามิเตอร์สี่ตัว ได้แก่ สองชื่อ ( name1และname2) และสองเพศ ( genderและgender2)

สำหรับการรวมเพศทุกครั้งฉันมีเอาท์พุทที่แตกต่างกัน

ตัวอย่างเช่น: ถ้าเพศ 1 คือM(ชาย) และเพศ 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"และอีกหลายอย่างที่ฉันไม่มีเวลาแปล

ฉันจะลดคำสั่ง double switch นี้ได้อย่างไร

การวางสวิตช์ตัวที่สองในเมธอดไม่ใช่ตัวเลือกเนื่องจากยังมีกรณีที่ชื่อทั้งสองเหมือนกันแล้วควรรวมเอาท์พุทเช่น: "Dear Sir and Madame name1,"



1
ถ้าภาษาของคุณให้มันสลับกับการแสดงออกที่แตกต่างกันไปทั้งสองgender1+gender2ค่าเช่น
Kilian Foth

3
ในจุดที่ไม่เกี่ยวข้องกับชื่อเพศหญิงจะใช้ที่นี่เป็นไม่ได้ Madam เป็นรูปแบบฝรั่งเศส MadameMadame
rojomoke

3
ไม่จำเป็นเล็กน้อย แต่ความจริงที่ว่าตัวแปร 'เพศ' ของคุณอาจเป็น 'ผู้ชาย', 'ผู้หญิง' หรือ 'ความสัมพันธ์' นั้นค่อนข้างรบกวน ...
Paddy

4
"โปรดทราบว่าฉันมีตัวเลือกหลายเพศ"ดีที่แน่นอนในสมัยนี้ ...
Lightness Races ใน Orbit

คำตอบ:


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
@Dupuplicator ทำตามค่าเริ่มต้นและจัดการกรณีพิเศษแยกกัน
Val

17
... และสร้างฟังก์ชั่นgenderToTitleเพื่อที่คุณไม่ต้องทำซ้ำหรือไม่? (หรือใช้ลูป)
Bergi

18

วิธีการแก้ปัญหาแบบรุนแรง: ให้ผู้ใช้ระบุชื่อของตนเอง (จากรายการที่กำหนดไว้ล่วงหน้าที่คุณให้ไว้)

วิธีแก้ปัญหาของคุณ (เมื่อมองผ่านสายตาภาษาอังกฤษ) จะปรากฏขึ้นเพื่อรองรับ Lords ("Sir") และสุภาพสตรีเท่านั้น ผู้ชายส่วนใหญ่จะพูดว่า "Mr" ผู้หญิงส่วนใหญ่เป็น "Miss", "Mrs" หรือ "Ms" ทั้งนี้ขึ้นอยู่กับสถานะสมรสและความคิดเห็นส่วนตัว จากนั้นก็มีฆ่าทั้งสุภาพอื่น ๆ ตามอันดับมืออาชีพ - "แพทย์", "อาจารย์", "Reverends" และแม้กระทั่งถ้าคุณรู้สึกกำลังจริงๆในแง่ดีเกี่ยวกับเว็บไซต์ของคุณ "ความศักดิ์สิทธิ์"!

วิธีแก้ปัญหาที่ง่ายกว่า: คุณต้องการฟังก์ชั่น [เดี่ยว] เพื่อแปล "เพศ" เป็นคำชมเชย รหัสครั้งเดียวและเรียกมันสำหรับทั้งสองคน:

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

ปัญหาที่นี่คือ: ฉันไม่สามารถควบคุมฐานข้อมูลใด ๆ แต่ขอขอบคุณสำหรับข้อมูลเพิ่มเติมของคุณขอขอบคุณ :)
moffeltje

8
Dear Sirเป็นรูปแบบของที่อยู่เป็นที่ยอมรับอย่างสมบูรณ์สำหรับผู้ชายทุกคน ฉันเห็นด้วยว่าในฐานะชื่อ Sir (ในSir Phill) ควรถูก จำกัด ให้เป็นอัศวิน (ไม่ใช่ขุนนาง) แต่นั่นเป็นเรื่องที่แตกต่าง
rojomoke

1
ฉันไม่เห็นว่าจะต้องเข้าถึงฐานข้อมูลอย่างไร สำหรับฉันนี่เป็นวิธีที่สะอาดที่สุดในการทำสิ่งนี้ มีการลดสวิทช์ที่ดีอื่น ๆ แต่นี่เป็นการทดแทนที่สะอาดที่สุดรวมถึงการปรับตรรกะอย่างดี
Dan

4
@rojomoke ไม่นั่นไม่ใช่เรื่องอื่น คำถามนี้เกี่ยวกับ "ท่านที่รัก (ใส่ชื่อที่นี่)" ไม่ใช่เรื่องธรรมดา "ท่านที่รัก" "รักเซอร์ (ใส่ชื่อที่นี่)" จะใช้ "เซอร์" เป็นชื่อเรื่อง
hvd

หน้าลงทะเบียนผู้ใช้ใบปลิวของ BA บ่อยครั้งประมาณปี 2003 มี "ความศักดิ์สิทธิ์ของเขา" ในรายการแบบหล่นลงของชื่อ ยังคงทำเพื่อทุกสิ่งที่ฉันรู้ ฉันจำได้ว่าเพราะเมนูแบบเลื่อนลงนั้นนานจนทำให้เบราว์เซอร์พกพาที่เราทำการผสานรวม ผมอยากแนะนำให้สนามฟรียกเว้นบริติชแอร์เวย์โดยเฉพาะอย่างยิ่งที่น่าจะให้คำปรึกษาและสมุดรู้หลายรูปแบบของชื่อบริบทที่แตกต่างกันในแต่ละ (ที่อยู่ซองแตกต่างกันและทักทายเป็นอย่างน้อย)
สตีฟเจสซอพ

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 initializer ไวยากรณ์และทำให้มันเป็น:static const static const map<string, string> titles{make_pair("M", "Sir"), make_pair("F", "Madam")};ทีนี้ใคร ๆ ก็สามารถลาconstออกได้หากการแก้ไขควรได้รับอนุญาต
Deduplicator

@Dupuplicator แน่นอนมีวิธีที่ดีกว่า ฉันไปเพื่อความเรียบง่ายที่นี่เนื่องจากไม่มีแท็กภาษา แต่ดูเหมือนว่า C ++ แต่คุณถูกต้องสมมติว่า C ++ 11

3

คำตอบของ ratchet freakค่อนข้างเป็นความคิดที่ดีถ้าประโยคต่าง ๆ มีรูปแบบที่เหมือนกัน แต่มีสิ่งที่ใส่เข้าไปสองอันโดยแต่ละอันขึ้นอยู่กับ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

แน่นอนว่าในขณะที่คุณได้รับอินพุตทั้งสี่ (2 ชื่อและ 2 เพศ) จากฐานข้อมูลการเพิ่มตารางอื่นและเข้าร่วมในการรับคำทักทายที่เหมาะสมอาจมีความยืดหยุ่นและอาจง่ายกว่าที่กล่าวมา


2

หากภาษาของคุณอนุญาตให้คุณทำคุณสามารถเขียน

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

มันไม่จำเป็นต้องดีขึ้นกว่ารุ่นของคุณเนื่องจากยังคงมีการทำซ้ำ switchแต่ก็ไม่หลีกเลี่ยงการซ้อนกัน


5
ถ้าคุณทำเช่นนี้เพราะความรักของคัพเค้กวางไว้ในอาร์เรย์หรือบางสิ่งและกำจัดสวิตช์ .... คำทักทาย ['MM'] = "ท่านที่รัก"; คำทักทาย ['MF'] = "ถึงท่านผู้หญิงและท่านที่รัก"; WishSalutation = คำทักทาย [gender1 + gender2];
JDT


สิ่งที่เรียกว่าขึ้นอยู่กับภาษา แต่โดยทั่วไปแล้วเป็นชุดของคีย์และค่าใช่
JDT

1
มีการปรับแต่งเล็กน้อยซึ่งใช้งานได้กับภาษาใด ๆ : คำนวณจำนวนเต็มเดียวจากทั้งอักขระอินพุตและเปิดใช้ไม่ใช่ตัวเลข
Deduplicator

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.