2012-01-09 15 views
5

के लिए इनपुट स्ट्रिंग को विभाजित करना मैं अपने कैलकुलेटर के लिए उपयोगकर्ता द्वारा दिए गए इनपुट को विभाजित करने की कोशिश कर रहा हूं। उदाहरण के लिए, यदि उपयोगकर्ता "23 + 45 * (1 + 1)" इनपुट करता है तो मैं इसे [23, +, 45, *, (, 1, +, 1,) में विभाजित करना चाहता हूं]।कैलकुलेटर

उत्तर

7

आपकी खोज के लिए लेक्सर कहा जाता है। लेक्सर भाग में इनपुट को विभाजित करता है (जिसे टोकन कहा जाता है) जिसे आप पढ़ सकते हैं।

सौभाग्य से, आपका लेज़र बहुत सरल है और हाथ से लिखा जा सकता है। अधिक जटिल लेक्सर्स के लिए, आप flex (जैसे "द फास्ट लेक्सिकल एनालिज़र" - एडोब फ्लेक्स में) का उपयोग कर सकते हैं, या (चूंकि आप जावा का उपयोग कर रहे हैं) ANTLR (नोट, एएनटीएलआर केवल एक लेक्सर से कहीं अधिक है)।

बस नियमित अभिव्यक्तियों की एक सूची के साथ आते हैं, प्रत्येक टोकन से मिलान करने के लिए एक (ध्यान दें कि चूंकि आपका इनपुट इतना आसान है, तो आप शायद इस सूची से दूर हो सकते हैं और उन्हें सभी को एक एकल रेगेक्स में विलय कर सकते हैं। हालांकि, के लिए अधिक उन्नत लेक्सर्स, यह प्रत्येक टोकन के लिए एक रेगेक्स करने में मदद करता है) उदाहरण के लिए

\d+ 
\+ 
- 
* 
/
\(
\) 

फिर एक पाश शुरू: जबकि वहाँ अधिक वर्ण पार्स किया जा सकता है, अपने रेगुलर एक्सप्रेशन से प्रत्येक के माध्यम से जाने के लिए और उन्हें स्ट्रिंग की शुरुआत के खिलाफ मैच के लिए प्रयास करते हैं। यदि वे मेल खाते हैं, तो पहले मिलान किए गए समूह को अपनी इनपुट सूची में जोड़ें। अन्यथा, मिलान करना जारी रखें (यदि उनमें से कोई भी मेल नहीं खाता है, तो उपयोगकर्ता को बताएं कि उनके पास सिंटैक्स त्रुटि है)।

स्यूडोकोड:

List<String>input = new LinkedList<String>(); 
while(userInputString.length()>0){ 
    for (final Pattern p : myRegexes){ 
     final Matcher m = p.matcher(userInputString); 
     if(m.find()) { 
      input.add(m.group()); 
      //Remove the token we found from the user's input string so that we 
      //can match the rest of the string against our regular expressions. 
      userInputString=userInputString.substring(m.group().length()); 
      break; 
     } 
    } 
} 

कार्यान्वयन नोट:

  • आप अपने रेगुलर एक्सप्रेशन के सभी के लिए ^ चरित्र पहले जोड़ें कर सकते हैं। यह सुनिश्चित करता है कि आप स्ट्रिंग की शुरुआत के खिलाफ अपने मैचों को एंकर करें। मेरा छद्म कोड मानता है कि आपने यह किया है।
0

यह थोड़ा सा मैला हो सकता है, क्योंकि मैं अभी भी सीख रहा हूं, लेकिन यह उन्हें तारों में विभाजित करता है।

सार्वजनिक वर्ग TestClass {

public static void main(String[] args) 
{ 
    Scanner sc = new Scanner(System.in); 
    ArrayList<String> separatedInput = new ArrayList<String>(); 
    String input = ""; 

    System.out.print("Values: "); 
    input = sc.next(); 

    if (input.length() != 0) 
    { 
     boolean numberValue = true; 
     String numbers = ""; 

     for (int i = 0; i < input.length(); i++) 
     { 
      char ch = input.charAt(i); 
      String value = input.substring(i, i+1); 

      if (Character.isDigit(ch)) 
      { numberValue = true; numbers = numbers + value; } 

      if (!numberValue) 
      { separatedInput.add(numbers); separatedInput.add(value); numbers = ""; } 
      numberValue = false; 

      if (i == input.length() - 1) 
      { 
       if (Character.isDigit(ch)) 
       { separatedInput.add(numbers); } 
      } 
     } 

    } 
    System.out.println(separatedInput); 
} 

}

1

मैं संकार्य और ऑपरेटर विभाजित है और मूल्यांकन अभिव्यक्ति अधिक उचित होगा करने के लिए ढेर का उपयोग कर लगता है। गणक में हम अंकगणितीय अभिव्यक्ति को परिभाषित करने के लिए आम तौर पर इन्फिक्स नोटेशन का उपयोग करते हैं।

Operand1 op Operand2 

चेक Shunting-yard algorithm इस तरह के कई मामलों में इस्तेमाल किया गणितीय अभिव्यक्ति पार्स करने के लिए। This भी एक अच्छा पढ़ा है।

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