Lab 12: 整數指令列四則計算機
Lab 12-1: 整數指令列四則計算機顯示 (40%)
- 輸入:包含整數 (符合
long
型態) 的四則計算運算式- 用空白字元分開整數數字及運算子,如:
1 + 2 * 3
、1 2 3 4 * + -
。
- 用空白字元分開整數數字及運算子,如:
- 輸出:顯示使用者輸入的整數數字及運算子。
- 數字:
1 2 3
、1 2 3 4
。 - 運算子:
+ *
、* + -
。
- 數字:
- 檔名:lab12_1_<學號>.cpp (e.g. lab12_1_106062802.cpp)
Notice:
- 程式需提示使用者輸入運算式,程式需分析後顯示使用者輸入的整數數字及運算子。
- 程式需檢查數字跟運算子的數量是否相符,若不相符則顯示錯誤訊息
Invalid expression.
並結束程式。- Example:使用者輸入 4 個數字,但運算子只有 2 個,並非 3 個,則顯示錯誤訊息
Invalid expression.
並結束程式。
- Example:使用者輸入 4 個數字,但運算子只有 2 個,並非 3 個,則顯示錯誤訊息
- 程式需檢查運算子是否為 '+'、'-'、'*'、'/',若不相符則顯示錯誤訊息
Invalid expression.
並結束程式。 - 程式需使用 function 來處理整數指令列四則計算機的輸入與輸出。
- 程式需在 30 秒之內執行完畢,所有測資皆不會超過 30 秒的執行時間。
Format
Please input the expression: <expression, space seprated>⏎
Operands: <numbers, space seprated>
Operators: <operators, space seprated>
Example
$ ./a.out⏎
Please input the expression: 1 2 3 4 * + -⏎
Operands: 1 2 3 4
Operators: * + -
$ ./a.out⏎
Please input the expression: -1 -2 -3 -4 * + -⏎
Operands: -1 -2 -3 -4
Operators: * + -
$ ./a.out⏎
Please input the expression: -1 -2 * -3 + -4 -⏎
Operands: -1 -2 -3 -4
Operators: * + -
$ ./a.out⏎
Please input the expression: -1 -2 -3 -4 * +⏎
Invalid expression.
$ ./a.out⏎
Please input the expression: -1 -2 -3 * + -⏎
Invalid expression.
$ ./a.out⏎
Please input the expression: -1 -2 -3 -4 * + %⏎
Invalid expression.
Pseudo Code
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void parse_expression(const string &expression, vector<string> &tokens);
bool check_expression(const vector<string> &tokens);
void print_ops(const vector<string> &tokens);
void print_nums(const vector<string> &tokens);
int main(int argc, char *argv[])
{
string input_buffer;
vector<string> tokens;
cout << "Please input the expression: ";
std::getline(cin, input_buffer);
parse_expression(input_buffer, tokens);
if (!check_expression(tokens))
{
cout << "Invalid expression." << endl;
return EXIT_FAILURE;
}
print_ops(tokens);
print_nums(tokens);
return EXIT_SUCCESS;
}
Reference:
Reference Code:
2-passes parsing: Credit: 賴杰弘 (110021118)
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
void parse_expression(const string &expression, vector<string> &check);
void parse_expression(
const vector<string> &check,
vector<long> &operands,
vector<string> &operators);
bool check_expression(const vector<string> &check);
void print_ops(const vector<long> &operands);
void print_nums(const vector<string> &operators);
int main(int argc, char *argv[])
{
string input_buffer;
vector<string> check;
vector<long> operands;
vector<string> operators;
cout << "Please input the expression: ";
getline(cin, input_buffer);
parse_expression(input_buffer, check);
if (!check_expression(check))
{
cout << "Invalid expression." << endl;
return EXIT_FAILURE;
}
parse_expression(check, operands, operators);
if ((operands.size() - 1) != operators.size())
{
cout << "Invalid expression." << endl;
return EXIT_FAILURE;
}
print_ops(operands);
print_nums(operators);
return EXIT_SUCCESS;
}
void parse_expression(const string &expression, vector<string> &check)
{
stringstream terms_extractor(expression);
for (string term; (terms_extractor >> term);)
{
check.push_back(term);
}
}
void parse_expression(
const vector<string> &check,
vector<long> &operands,
vector<string> &operators)
{
for (int i = 0; i < check.size(); i++)
{
if (check[i] == "+"
|| check[i] == "-"
|| check[i] == "*"
|| check[i] == "/")
{
operators.push_back(check[i]);
}
else
{
long operand = stol(check[i]);
operands.push_back(operand);
}
}
}
bool check_expression(const vector<string> &check)
{
if ((check.size() % 2) == 0)
{
return false;
}
for (int i = 0; i < check.size(); i++)
{
string s = check[i];
if (s.size() == 1)
{
if (s[0] != '+'
&& s[0] != '-'
&& s[0] != '*'
&& s[0] != '/')
{
if (!isdigit(s[0]))
{
return false;
}
}
}
else
{
if (s[0] != '-')
{
if (!isdigit(s[0]))
{
return false;
}
}
for (int i = 1; i < check[i].size(); i++)
{
if (!isdigit(s[i]))
{
return false;
}
}
}
}
return true;
}
void print_ops(const vector<long> &operands)
{
cout << "Operands: ";
for (int i = 0; i < operands.size(); i++)
{
cout << operands[i] << " ";
}
cout << endl;
}
void print_nums(const vector<string> &operators)
{
cout << "Operators: ";
for (int i = 0; i < operators.size(); i++)
{
cout << operators[i] << " ";
}
cout << endl;
}
by character parsing: Credit: 吳咨萱 (110021132)
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void parse_expression(const string &expression, vector<string> &tokens)
{
int n = 0;
string stringtokens;
while (n <= expression.size() - 1)
{
if (expression[n] != ' ')
{
do
{
stringtokens.push_back(expression[n]);
n = n + 1;
} while (expression[n] != ' ' && n <= expression.size() - 1);
tokens.push_back(stringtokens);
stringtokens.clear();
}
else
{
n = n + 1;
}
}
}
bool check_expression(const vector<string> &tokens)
{
int operandsnum = 0;
int operatorsnum = 0;
for (int i = 0; i <= tokens.size() - 1; i++)
{
int j = 0;
if (tokens[i][j] == '-' && tokens[i].size() != 1)
{
for (int j = 1; j <= tokens[i].size() - 1; j++)
{
if (!isdigit(tokens[i][j]))
{
return false;
}
}
operandsnum = operandsnum + 1;
}
else if (tokens[i][j] == '+'
|| tokens[i][j] == '-'
|| tokens[i][j] == '*'
|| tokens[i][j] == '/')
{
if (tokens[i].size() != 1)
{
return false;
}
else
{
operatorsnum = operatorsnum + 1;
}
}
else
{
for (int j = 0; j <= tokens[i].size() - 1; j++)
{
if (!isdigit(tokens[i][j]))
{
return false;
}
}
operandsnum = operandsnum + 1;
}
}
if (operandsnum != operatorsnum + 1)
{
return false;
}
else
{
return true;
}
}
void print_ops(const vector<string> &tokens)
{
std::cout << "Operators: ";
for (int i = 0; i <= tokens.size() - 1; i++)
{
if (tokens[i] == "+"
|| tokens[i] == "-"
|| tokens[i] == "*"
|| tokens[i] == "/")
{
std::cout << tokens[i];
if (i != tokens.size() - 1)
{
std::cout << " ";
}
}
}
}
void print_nums(const vector<string> &tokens)
{
std::cout << "Operands: ";
for (int i = 0; i <= tokens.size() - 1; i++)
{
if (tokens[i] != "+"
&& tokens[i] != "-"
&& tokens[i] != "*"
&& tokens[i] != "/")
{
std::cout << tokens[i];
if (i != tokens.size() - 1)
{
std::cout << " ";
}
}
}
std::cout << "\n";
}
int main(int argc, char *argv[])
{
string input_buffer;
vector<string> tokens;
cout << "Please input the expression: ";
std::getline(cin, input_buffer);
parse_expression(input_buffer, tokens);
if (!check_expression(tokens))
{
cout << "Invalid expression." << endl;
return EXIT_FAILURE;
}
print_nums(tokens);
print_ops(tokens);
return EXIT_SUCCESS;
}
function of function: Credit: 陶威綸 (110021121)
#include <cstdlib>
#include <sstream>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void parse_expression(const string &expression, vector<string> &tokens);
bool check_expression(const vector<string> &tokens);
void print_ops(const vector<string> &tokens);
void print_nums(const vector<string> &tokens);
bool is_number(string num);
bool is_oper(string token);
int main(int argc, char *argv[])
{
string input_buffer;
vector<string> tokens;
cout << "Please input the expression: ";
std::getline(cin, input_buffer);
parse_expression(input_buffer, tokens);
if (!check_expression(tokens))
{
cout << "Invalid expression." << endl;
return EXIT_FAILURE;
}
print_nums(tokens);
print_ops(tokens);
return EXIT_SUCCESS;
}
void print_ops(const vector<string> &tokens)
{
cout << "Operators: ";
for (int i = 0; i < tokens.size(); i++)
{
if (is_oper(tokens[i]))
cout << tokens[i] << " ";
}
cout << endl;
}
void print_nums(const vector<string> &tokens)
{
cout << "Operands: ";
for (int i = 0; i < tokens.size(); i++)
{
if (is_number(tokens[i]))
cout << tokens[i] << " ";
}
cout << endl;
}
void parse_expression(const string &expression, vector<string> &tokens)
{
stringstream buffer(expression);
for (string tmp; (buffer >> tmp);)
{
tokens.push_back(tmp);
}
}
bool is_number(string num)
{
int suc_case = 0;
if (num[0] == '-' && num.size() != 1)
suc_case = 1;
for (int i = 0; i < num.size(); i++)
{
for (int tmp = 0; tmp < 10; tmp++)
{
if (num[i] - '0' == tmp)
{
suc_case += 1;
}
}
}
return suc_case == num.size();
}
bool is_oper(string token)
{
if (token.size() != 1)
return false;
string valid = "+-*/";
for (int i = 0; i < valid.size(); i++)
{
if (token[0] == valid[i])
return true;
}
return false;
}
bool check_expression(const vector<string> &tokens)
{
int numC = 0, operC = 0;
for (int i = 0; i < tokens.size(); i++)
{
if (is_number(tokens[i]))
numC += 1;
else if (is_oper(tokens[i]))
operC += 1;
else
return false;
}
return (numC - operC == 1);
}
try ... catch ...
: Credit: 陳柏志 (107021128)
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
void parse_expression(const string &expression, vector<string> &tokens);
bool check_expression(const vector<string> &tokens);
void print_ops(const vector<string> &tokens);
void print_nums(const vector<string> &tokens);
int main(int argc, char *argv[])
{
string input_buffer;
vector<string> tokens;
cout << "Please input the expression: ";
getline(cin, input_buffer);
parse_expression(input_buffer, tokens);
if (!check_expression(tokens))
{
cout << "Invalid expression." << endl;
return EXIT_FAILURE;
}
print_nums(tokens);
print_ops(tokens);
return EXIT_SUCCESS;
}
void parse_expression(string const &expression, vector<string> &tokens)
{
stringstream tokens_extractor(expression);
for (string new_token; (tokens_extractor >> new_token);)
{
tokens.push_back(new_token);
}
}
bool check_expression(const vector<string> &tokens)
{
int op_cnt = 0, num_cnt = 0;
for (int i = 0; i < tokens.size(); ++i)
{
if (tokens[i] == "+"
|| tokens[i] == "-"
|| tokens[i] == "*"
|| tokens[i] == "/")
{
++op_cnt;
}
else
{
try
{
stol(tokens[i]);
++num_cnt;
}
catch (const std::exception &e)
{
return false;
}
}
}
return num_cnt == op_cnt + 1;
}
void print_ops(const vector<string> &tokens)
{
cout << "Operators:";
for (int i = 0; i < tokens.size(); ++i)
{
if (tokens[i] == "+"
|| tokens[i] == "-"
|| tokens[i] == "*"
|| tokens[i] == "/")
{
cout << " " << tokens[i];
}
}
cout << endl;
}
void print_nums(const vector<string> &tokens)
{
cout << "Operands:";
for (int i = 0; i < tokens.size(); ++i)
{
try
{
long number = stol(tokens[i]);
cout << " " << number;
}
catch (const std::exception &e)
{
}
}
cout << endl;
}
TA version:
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void parse_expression(const string &expression, vector<string> &tokens);
bool check_expression(const vector<string> &tokens);
void print_ops(const vector<string> &tokens);
void print_nums(const vector<string> &tokens);
int main(int argc, char *argv[])
{
string input_buffer;
vector<string> tokens;
cout << "Please input the expression: ";
std::getline(cin, input_buffer);
parse_expression(input_buffer, tokens);
if (!check_expression(tokens))
{
cout << "Invalid expression." << endl;
return EXIT_FAILURE;
}
print_nums(tokens);
print_ops(tokens);
return EXIT_SUCCESS;
}
void parse_expression(const string &expression, vector<string> &tokens)
{
string temp;
for (int i = 0; i < expression.size(); i++)
{
if (expression[i] == ' ')
{
tokens.push_back(temp);
temp.clear();
}
else if (i == expression.size() - 1) // End of Input_Buffer
{
temp += expression.substr(i, 1);
tokens.push_back(temp);
}
else
temp += expression.substr(i, 1);
}
}
bool check_expression(const vector<string> &tokens)
{
int oper_counts = 0, num_counts = 0;
for (int i = 0; i < tokens.size(); i++)
{
if (tokens[i].length() == 1)
{
if (isdigit(tokens[i][0]))
{
num_counts++;
continue;
}
else
{
if (tokens[i][0] == '+'
|| tokens[i][0] == '-'
|| tokens[i][0] == '*'
|| tokens[i][0] == '/')
{
oper_counts++;
continue;
}
else
return false;
}
}
for (int j = 0; j < tokens[i].length(); j++)
{
if (!isdigit(tokens[i][j]))
{
if (j == 0 && tokens[i][j] == '-')
// Check if Negative Sign
continue;
return false;
}
}
num_counts++;
}
if (num_counts != oper_counts + 1)
return false;
return true;
}
void print_nums(const vector<string> &tokens)
{
cout << "Operands:";
for (int i = 0; i < tokens.size(); i++)
{
if (tokens[i].length() != 1 || isdigit(tokens[i][0]))
cout << ' ' << tokens[i];
}
cout << endl;
}
void print_ops(const vector<string> &tokens)
{
cout << "Operators:";
for (int i = 0; i < tokens.size(); i++)
{
if (tokens[i].length() == 1 && !isdigit(tokens[i][0]))
cout << ' ' << tokens[i];
}
cout << endl;
}