2010-09-05 20 views
12

में बहुत से मामले हैं मेरे पास कई मामले हैं और मैं बस सरल if ... if else ब्लॉक का उपयोग कर रहा हूं।जावा कोड में सुधार करें:

मैं इस कोड में if कथनों की संख्या को कैसे कम कर सकता हूं?

शायद मैं एक लुकअप टेबल का उपयोग कर सकता हूं, लेकिन मुझे यकीन नहीं है कि जावा में इसे कैसे कार्यान्वित किया जाए।

private int transition(char current, int state) 
{ 
    if(state == 0) 
    { 
     if(current == 'b') 
     { 
      return 1; 
     } 
     else 
      return 0; 
    } 
    if(state == 1) 
    { 
     if(current == 'a') 
     { 
      return 2; 
     } 
     else 
      return 0; 
    } 
    if(state == 2) 
    { 
     if(current == 's') 
     { 
      return 3; 
     } 
     else 
      return 0; 
    } 
    if(state == 3) 
    { 
     if(current == 'e') 
     { 
      return 3; 
     } 
     if(current == 'b') 
     { 
      return 4; 
     } 
     else 
      return 0; 
    } 
    if(state == 4) 
    { 
     if(current == 'a') 
     { 
      return 5; 
     } 
     else 
      return 0; 
    } 
    if(state == 5) 
    { 
     if(current == 'l') 
     { 
      return 6; 
     } 
     else 
      return 0; 
    } 
    else 
     return 0; 
} 
+12

देखो मा 'इतने सारे जादू नंबर! 1, 2, 3, 4, 5, 6 इत्यादि के बजाय कुछ नामित स्थिरांक का उपयोग करने पर विचार करें क्योंकि 6 महीने में कोई भी याद नहीं रखेगा कि 1 या 2 का क्या मतलब था। –

+1

हर किसी की मदद के लिए धन्यवाद। भले ही मैं सभी समाधानों को स्वीकार नहीं कर सका, मैंने आपके प्रत्येक उत्तर से कोडिंग के बारे में कुछ और सीखा, इसलिए मैं सहायता की बहुत सराहना करता हूं। आपका रविवार शुभ हो। – PFranchise

उत्तर

32

जो आप करने की कोशिश कर रहे हैं वह एक सीमित राज्य मशीन की तरह दिखता है, और इन्हें आमतौर पर एक संक्रमण तालिका की सहायता से लागू किया जाता है। एक बार जब आप टेबल सेट अप कर लेते हैं, तो यह केवल उस स्थिति को अनुक्रमणित करने का मामला है जिसे आप रिटर्न वैल्यू प्राप्त करना चाहते हैं। मान लें कि आपके रिटर्न वैल्यू 256 से कम हैं, आप 2 डी बाइट सरणी का उपयोग कर सकते हैं:

byte table[][] = new byte[NUM_STATES][NUM_CHARACTERS]; 
// Populate the non-zero entries of the table 
table[0]['b'] = 1; 
table[1]['a'] = 2; 
// etc... 

private int transition(char current, int state) { 
    return table[state][current]; 
} 
+2

+1 - बिल्कुल, बहुत अच्छा। – duffymo

+0

हाहा यह वही है जो मैं ढूंढ रहा था। मैं वास्तव में एक परिमित राज्य मशीन लागू कर रहा हूँ। – PFranchise

+0

अगर मैं आप थे तो मैं इसे स्वीकार करूंगा। यह अब तक का सबसे अच्छा जवाब है। – duffymo

6

मैं स्विच बयान यहाँ सबसे अच्छा होगा:

private int transition(char current, int state) 
{ 
    switch(state) 
    { 
     case 0: 
      return current == 'b' ? 1 : 0; 
     case 1: 
      return current == 'a' ? 2 : 0; 
     case 2: 
      return current == 's' ? 3 : 0; 
     case 3: 
      return current == 'e' ? 3 : (current == 'b' ? 4 : 0); 
     case 4: 
      return current == 'a' ? 5 : 0; 
     case 5: 
      return current == 'l' ? 6 : 0; 
     default: 
      return 0; 
    } 
} 

और एक नोट, वहाँ केवल 5 बयान वहाँ शुद्ध intergers पता चल सके कि, यह वास्तव में एक ओवरहेड है।

+0

@RobertPitt धन्यवाद! मैं अतिरिक्त प्रतिक्रिया की सराहना करता हूं। – PFranchise

+0

अपने तर्क को पूरा करने के लिए अद्यतन किया गया है। – RobertPitt

+0

कोड को और भी कम करने के लिए, यदि आप शॉर्ट हैंड लॉजिकल का उपयोग करते हैं और आप उन्हें 1 लाइन पर रखते हैं तो आप 'ब्रेक' कमांड को हटा सकते हैं, अगर जावा के पास इसके व्याख्याता के भीतर है। – RobertPitt

9

पर विचार इंटरफेस + enums:

interface State<T> 
{ 
    public void State<T> step(T input); 
} 

enum MyState implements State<Character> { 
    STATE0(0) { @Override public void MyState step(Character c) { return c == 'b' ? STATE1 : STATE0; }}, 
    STATE1(1) { @Override public void MyState step(Character c) { return c == 'a' ? STATE2 : STATE0; }}, 

    /* rest of states here */ 

    final private int value; 
    MyState(int value) { this.value = value; } 
    public int getValue() { return this.value; } 
} 

class SomeClass 
{ 
    public MyState currentState = STATE0; 

    public void step(char input) 
    { 
     this.currentState = this.currentState.step(input); 
    } 
} 
2

उपयोग switch बाहरी if श्रृंखला के लिए बयान:

switch (state) { 
    case 0: <code> ; break; 
    case 1: <code> ; break; 
    case 2: <code> ; break; 
    <etc> 
    default: return 0; break; 
} 
14

ठीक है, आप आसानी से hash उपयोग कर सकते हैं। सरल और साफ

// declare hashtable 
    Map<String, Integer> map = new HashMap<String, Integer>(); 
    map.put("0-b", 1); 
    map.put("1-a", 2); 
    map.put("2-s", 3); 
    ... 

    // get result 
    Integer result = map.get(state + "-" + current); 
    // change null (nothing found) to zero 
    return result == null ? 0 : result; 
+0

निष्पादन के अनुसार, क्या एक नई कक्षा बनाने के लिए बेहतर नहीं होगा जिसमें अंक और चार हो और उसके पास हैश फ़ंक्शन है जो एक अद्वितीय हैश उत्पन्न करता है ताकि हैश तालिका तेज प्रदर्शन कर सके? – alternative

+0

@mathepic निश्चित रूप से, सुधार के लिए बहुत सारे कमरे हैं।(हालांकि आप पाते हैं कि अद्वितीय हैश फ़ंक्शन बनाना हमेशा आसान नहीं होता है, खासकर जब राज्यों की संख्या बढ़ती है)। मैं बस लुकअप टेबल के सरल और साफ उदाहरण प्रदान करना चाहता था। और ऐसा नहीं है जैसे हैश मैप में अन्य तरीकों की तुलना में बहुत अधिक उपर है, जैसे कि एक या दो-आयामी सरणी। –

+0

हाँ, मैं सिर्फ एक सुझाव दे रहा था। +1। – alternative

5

ऐसा लगता है कि आपको एक सीमित राज्य मशीन के लिए बेहतर अमूर्तता की आवश्यकता है। एक वर्ग के बारे में सोचें जो आप बेहतर तरीके से चाहते हैं कि आप कोड को संशोधित करने के बजाय कॉन्फ़िगरेशन द्वारा बढ़ा सकते हैं।

+0

टिप के लिए धन्यवाद। मैं चिंतित था कि मैं बहुत ज्यादा कोडिंग कर रहा था। मैं इस बारे में पुनर्विचार करूँगा जिस तरह से मैं इसके बारे में जा रहा हूं। – PFranchise

+0

+1 मेरी विनम्र राय में यहां सबसे अच्छा सुझाव है। जब मैं बहुत सारे देखता हूं, तो मेरे दिमाग में आने वाली पहली बात 'विरासत का उपयोग करें' है। – helpermethod

+0

एक सामान्य नियम के रूप में, आप * हमेशा * polymorphism के साथ स्थितियों को प्रतिस्थापित कर सकते हैं। आखिरकार, एक विशाल स्विच स्टेटमेंट नहीं होने पर गतिशील विधि प्रेषित क्या है? स्मॉलटाक, उदाहरण के लिए, * कोई * सशर्त नहीं है, * सबकुछ * विधि प्रेषण के माध्यम से किया जाता है। –

5

यदि यह कोड उस समय विस्तारित होने वाला है, तो राज्य मशीन का उपयोग क्यों न करें? प्रत्येक राज्य अगले राज्य को प्राप्त चरित्र के आधार पर वापस कर देगा। शायद यह इस कोड के लिए एक ओवरकिल है, लेकिन इसे बनाए रखने के लिए बहुत आसान हो जाएगा, & का विस्तार करें।

+0

कोड लगभग हमेशा बदलता है! –

संबंधित मुद्दे