2012-10-18 72 views
2

我有以下問題: 我有一個如下所示的輸入字符串: string s =「87635 + 23754 * ar + ar * var * 0.895 +(ar -var)+ AR * AR + VAR * VAR「;如何在C++中將字符串拆分成不同的數據類型

我想分割這個字符串並執行每個操作,即我想讀取所有的值,執行數學運算並輸出C++中的最終答案。我該怎麼做? getline命令只能分割一種類型的分隔符。我該如何解決這個問題?

感謝

丹田

回答

2

的「正確」的答案是寫你的小型語言解析器,但它可能是簡單的使用string::find_first_of和/或string::find_first_not_of將其標記化到數字,運營商和命名變量

+0

演示:http://ideone.com/wVqRw –

1

看看std::stringstream。您可以將一個字符串放入流中,並從std :: cin中讀取它!

例如:

#include <iostream> 
#include <sstream> 

int main() 
{ 
    std::stringstream stream(std::stringstream::in | std::stringstream::out); 
    stream << "22+2"; 

    int operand1, operand2; 
    char op; 

    stream >> operand1; 
    stream >> op; 
    stream >> operand2; 

    std::cout << operand1 << " " << op << " " << operand2 << std::endl; 

    return 0; 
} 

對於更復雜的例子看dc-clone我做了,而前:gist.github.com/ae6ebe58a286d6cfd847。特別是看看467-522行(主要)。

+0

它的棘手處理'4+(4 + 4)'如果你認爲操作數運算操作數-op-operand等 –

+0

是的,也有人必須知道有多少操作數和操作員在那裏。如果我需要將其留給用戶輸入,則難以實現。還有其他建議嗎? – user1705329

+0

看看我張貼的更復雜的例子。雖然它使用的是後綴表示法,但它不應該像解析中綴表示法那樣產生如此大的差異。我認爲最好的辦法是,將中綴表示法轉換爲使用堆棧的後綴,然後執行每一個操作。下面是一個簡單的算法:http://scriptasylum.com/tutorials/infix_postfix/algorithms/infix-postfix/index.htm – chrert

1

您必須編寫一個解析器。不要害怕「正確」的解決方案,這是正確的,有充分的理由;有用。其他人提供的捷徑不會讓你的任務變得更輕鬆。

我已經包含了一個基本的解決方案,您可以將其作爲一個起點。您應該構建測試用例以確保它是正確的,並更徹底地處理錯誤案例。

希望通過研究這些代碼,你將會得到遞歸裁剪解析器的總體思想。我們通過對不同級別的運算符優先級使用單獨的函數來分解解析問題。這些函數以自頂向下的方式相互調用,使得這種類型的解析器更易於理解。

我編寫它的方式是簡短的。如果您認爲'goto'是邪惡的,請改用while循環。此外,將解析函數轉換爲Parser類以擺脫全局變量。

好運和幸福的解析:)

#include <string> 
    #include <map> 
    #include <iostream> 
    #include <sstream> 
    using namespace std; 

    stringstream ss; 
    map<string,double> variables; 
    string err_string = ""; 

    double parse_add_exp(); 

    int main() 
    { 
     // get the expression and variables 
     ss << "87635+23754*ar+ar*var*0.895+(ar-var)+ar*ar+var*var"; 
     variables["ar"] = -4.5; 
     variables["var"] = 141.26f; 
     try 
     { 
      // calculate the result 
      double result = parse_add_exp(); 
      if(result == INFINITY) 
       cout<<"Runtime error: Division by zero"<<endl; 
      else 
       cout<<"Result = "<<result<<endl; // prints 'Result = 1.95143' 
     } 
     catch (const char * error) 
     { 
      cout<<"Invalid expression: "<<error<<endl; 
     } 
     return 0; 
    } 
    double parse_number() 
    { 
     double f; 
     if(!(ss>>f)) 
      throw "Expected number"; 
     return f; 
    } 
    double parse_operand() 
    { 
     string var(""); 
     while(isalpha(ss.peek())) 
      var += ss.get(); 
     if(!var.size()) 
      return parse_number(); 
     if(variables.find(var) == variables.end()) 
      throw "Variable is undefined"; 
     return variables[var]; 
    } 
    double parse_parenthesis() 
    { 
     if(ss.peek() != '(') 
      return parse_operand(); 
     ss.get(); 
     double f = parse_add_exp(); 
     if(ss.get() != ')') 
      throw "Expected closing parenthesis"; 
     return f; 
    } 
    double parse_mul_exp() 
    { 
     double product = parse_parenthesis(); 
    PEEKOP: 
     switch(ss.peek()) 
     { 
      case '*': ss.get(); product *= parse_parenthesis(); goto PEEKOP; 
      case '/': ss.get(); product /= parse_parenthesis(); goto PEEKOP; 
      default: return product; 
     } 
    } 
    double parse_add_exp() 
    { 
     double sum = parse_mul_exp(); 
    PEEKOP: 
     switch(ss.peek()) 
     { 
      case '+': ss.get(); sum += parse_mul_exp(); goto PEEKOP; 
      case '-': ss.get(); sum -= parse_mul_exp(); goto PEEKOP; 
      default: return sum; 
     } 
    } 
相關問題