Меня задали вопрос в интервью и хочу знать программный подход для его решения.
Que: У нас есть текстовый файл, который содержит операцию, которая должна выполняться в программе. Пользователь может обновить этот текстовый файл и изменить операцию, т.е. Текстовый файл может содержать + для сложения или - для вычитания. Программа имеет две переменные, то есть a и b, чтение текстового файла, выполнение операции и результат отображения. Если текстовый файл содержит +, то программа должна возвращать сумму a и b, а если текстовый файл имеет - тогда программа должна возвращать ab. Пользователь может поместить любую операцию в текстовый файл.
Я дал два подхода:
Программа может иметь оператор switch. Если текстовый файл имеет +, оператор проверки программы и выполняет операцию + b в соответствии с оператором switch, например, для других операций. Этот ответ был отклонен, поскольку мы должны жестко закодировать все возможные операции в коммутаторе.
Я могу использовать oracle и запускать запрос для любой операции, т.е. Если в текстовом файле есть +, тогда я могу создать строку sql, например 'select a + b в: result from dual;' и запустить встроенный sql в программе. База данных будет выполнять sql и возвращать выходные данные для любой действительной операции, и программе не нужно жестко кодировать все возможные операции. Я дал этот ответ, поскольку я давал интервью для C++/C и pro * c. Но и этот подход не был удовлетворен.
Итак, каков наилучший подход к решению этой проблемы с помощью программы?
Вероятно, что-то вроде этого, таблица поиска для функций с похожим прототипом
int add(int a,int b)
{
return a+b;
}
int sub(int a,int b)
{
return a-b;
}
typedef int (*function_cb)(int,int);
std::map<string, function_cb> callBacks;
.....
void init_lookup()
{
callBacks["+"] = &add;
callBacks["-"] = ⊂
}
И затем используйте его на основе вашего текстового файла
int res = callBacks["-"](8,4);
Где -
, 8
, 4
из вашего текстового файла
По-моему, они просто хотят прочитать символ +, -, * и поместить этот символ между переменными и выполнить инструкцию.
как преобразовать строку в выражение см. этот ответ Преобразование строки в математическую оценку
Я думаю, что эти вопросы в большей степени связаны с перегрузкой оператора, вы можете определить, какие обычные операторы будут делать, когда операнды являются функциями/отличными от стандартных переменных.
Для чтения выражения из входного файла вы можете использовать стандартный метод чтения, который предлагает Стандартная библиотека:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main () {
string line;
ifstream myfile ("example.txt");
if (myfile.is_open())
{
while ( getline (myfile,line) )
{
cout << line << '\n';
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
(код взято cplusplus.com)
О переводе этой строки из файла... вы глубоко вникаете в деревья выражений. Для работы с деревьями выражений вы можете ознакомиться с приведенным ниже кодом. Это то, что я написал в прошлом, чтобы объяснить кому-то об этой концепции:
class Token
{
public:
enum TokenTypes { operator_token, operand_token };
Token();
Token( std::string token );
~Token(); // we are not inheriting, so no need to be virtual
Token(const Token &in);
Token& operator=(const Token &in);
TokenTypes getId() const;
// you need to set the left/right from addToken(), see class Tree
void setLeft(Token* left);
void setRight(Token* right);
const Token* getLeft();
const Token* getRight();
private:
// when creating the Token you need to be able to identify
// what TokenType the string is
TokenTypes tokenId( std::string token );
TokenTypes m_id; // type of token
std::string m_token; // the actual string token e.g. "+", "12", ..
Token* m_left; // the pointers to the children left or right in a binary tree
Token* m_right;
};
class Tree
{
public:
Tree();
~Tree(); // clean up
void addToken( std::string token ); // this adds a token to the tree
private:
Token* m_root;
};
вы можете использовать его так...
std::string strToken
Tree T;
while ( getNextStringToken(strToken) )
{
Token* newToken = new Token(strToken);
T.addToken(newToken);
}
Вы можете больше узнать об этой концепции в Википедии.
Я надеюсь, это поможет вам!
.close()
, .is_open()
вместо логического преобразования, using namespace std
и т. Д.