[英]other ideas for calculating a string that contains e.g. “5 + 3 / 2”
我已經編寫了一個程序,您在其中輸入一個字符串。 該字符串應為常規術語,例如“ 5 + 3/2”,並且所有數字和運算符都必須通過空格分隔。 您可以輸入的術語應盡可能長,例如“ 1 * 2 * 5-1 * 4 +1 + 5 + 3 + 3 + 3”也應該起作用。 +,-,*和/是唯一允許使用的運算符。
我已經有了工作代碼。 但忽略了*和/以及+和-之前的事實。 但它可以完美地完成其他所有工作。 這個想法是創建兩個數組,一個數組將運算符保存在char數組中(稱為char operator []),另一個數組將整數保存在float數組中(稱為float values [])。 那么我有這種計算方法:
void calc(float values[], char operators[]) {
float res_final;
float res_array[10];
int counter = (sizeof(values) / sizeof(*values));
for (int i = 0; i < getBorder(values); i++) {
if (i == 0) {
res_array[i] = switchFunction(values[i], values[i + 1], operators[i]);
}
res_final = switchFunction(res_array[i], values[i + 2], operators[i + 1]);
res_array[i+1] = res_final;
if (i == getBorder(values)) {
break;
}
}
std::cout << "evaluation of expression is: " << res_final << std::endl;
}
float switchFunction(float val_1, float val_2, char op) {
switch (op) {
case '+': return val_1 + val_2;
break;
case '-': return val_1 - val_2;
break;
case '*': return val_1 * val_2;
break;
case '/': return val_1 / val_2;
break;
}
return 0;
}
好的代碼不是很漂亮,但是我無法提出更多有用的東西。 我有很多想法,但是對於操作員來說,一切都失敗了。 我想在'+'中定義普通的+,其余的也一樣,但是這行不通。
因此,如果您對如何在行前包含點有任何建議,或者您有完全不同的方法來進行挖掘,我將很高興聽到它:)
從長遠來看,您想創建一個代表公式的對象。
一個好的結構就是一棵樹。 這樣的樹的內部節點是運算符,而葉子是數字。
然后,編寫一個將字符串解析為樹的解析器。 我會像這樣遞歸執行:
FormulaNode parse(input){
string left, right;
if(split_string(input, * or /, left, right){
return FormulaNode(* or /, parse(left), parse(right))
if(split_string(input, + or -, left, right){
...
}
return FormulaNode(number, to_value(string))
}
使用split_string是一種方法,該方法嘗試按某個符號將字符串拆分,如果可能的話返回一個布爾值,並將其拆分為左右引用,
FormulaNode(symbol, left child, right child)
是創建內部節點的構造函數,
FormulaNode(number, value)
是創建葉子的構造函數。
當然,所有這些都是偽代碼,不想只是為了說明原理就強加給您樣式。 第二個構造函數可能僅是簽名FormulaNode(const double)
。 至於符號,我建議創建像enumerate OperatorType {addition,...}
。
編輯:
這是一個更大的架構,其設計有些不同:
class FormulaTree{
private:
class FormulaNode{
private:
bool is_number;
//used members if is number
double value;
//used members if not is number / is operator
OperatorType type;
unique_ptr<FormulaNode> left_child, right_child;
public:
FormulaNode(string input);
double evaluate() const;
};
unique_ptr<FormulaNode> root;
public:
Formula(string input);
double evaluate() const;
}
與(以偽代碼)
FormulaTree::FormulaNode::FormulaNode(string input){
if(input contains * or /){
char symbol = first occurence(input, * or /);
vector<string> split_input= split at first occurence(input, symbol);
type = OperatorType(symbol);
is_number = false;
left_child = make_unique(new FormulaNode(split_input[0]));
right_child = make_unique(new FormulaNode(split_input[1]));
return;
}
if(input contains + or -){
...
}
is_number = true;
value = parse to int(input);
}
(從長遠來看,您可能還想添加一些檢查輸入是否合法的內容,例如“運算符一側的字符串不為空”,“解析為int有效,不包含任何非法字符”等)等等)
(此外,如果繼續擴展此功能,則需要一些解析器,該解析器首先將其用方括號分隔)
如果您需要我解釋有關此結構的任何內容,只需問一下,我將進行編輯。
編輯:
Slava評論說,最好為不同類型派生FormulaNode。 沒錯,我本來是為了顯示這種設計而對其進行編輯的,但由於它可能會使初學者容易混淆,因此我再次將其刪除。
尤其是由於這種模式將需要稍微不同的布局-我們希望讓樹本身進行解析,因為派生類之間不應該相互了解。 從長遠來看,您想學習這樣的東西。 我建議您嘗試一下我介紹的模式,添加自己的樣式,添加更多功能(例如,用於加電的符號或使用負號表示負數的選項),然后將其放在CodeReview上 。 我的推理是,無論如何,這就是您想要做的,並且當您這樣做時,無論如何,您的代碼都會受到攻擊,直到“完美”為止。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.