К сожалению, это не так просто, как ожидалось.
Нам нужно разбить задачу на более мелкие части.
То, что вы хотите сделать, - это разбить ваше уравнение по терминам и извлечь из этого коэффициенты и показатели.
Разделение чего-либо на похожие части также называется токенизацией.
Итак, ваше уравнение состоит из терминов, которые следуют одному и тому же шаблону. Сначала необязательный знак, за которым следуют коэффициенты, затем «X ^» и, в конце, показатель степени (который может иметь или не иметь знак).
И поскольку все термины имеют одинаковую структуру,мы можем найти их с помощью так называемого регулярного выражения. C ++ поддерживает эту функциональность. Также для разделения текста на более мелкие токены / термины / сопоставления с образцами у нас есть специальный итератор std::sregex_token_iterator
. Как и любой другой итератор в C ++, он перебирает исходную строку и извлекает (и копирует) все совпадающие шаблоны.
ОК, тогда мы уже нашли решение для первой подзадачи. Извлеките все термины и поместите их в std::vector
. Мы будем использовать конструктор диапазона std::vector
s, чтобы сделать это при определении переменной.
Следующий шаг - получить коэффициент. Здесь нам нужна особая обработка, потому что коэффициент можно опустить с предполагаемым 1. Используя это предположение, мы будем читать термин и преобразовывать коэффициент в целое число. И поскольку мы хотим сделать это в одном операторе, мы используем std::transform
из библиотеки алгоритмов STL.
Получение показателей проще. Мы просто конвертируем что-либо в члене после знака «^» в целое число. Мы снова используем std::transform
для работы со всеми терминами в одном выражении.
И последнее, но не менее важное: мы получим правую часть уравнения и преобразуем его также в целое число.
Обратите внимание:
Все это можно сделать также со значениями типа с плавающей запятой. Мы также можем разрешить пробелы в уравнении
. Для этого мы просто изменим строку std::regex
.
См. Полный пример ниже:
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <regex>
#include <algorithm>
#include <iomanip>
int main() {
std::string equation{ "5X^6+X^2+X^1-4X^0=0" };
const std::regex re(R"(([+-]?\d?X\^[+-]?\d+))");
std::vector<std::string> terms{ std::sregex_token_iterator(equation.begin(), equation.end(), re,1),std::sregex_token_iterator() };
std::vector<int> coefficients(terms.size());
std::vector<int> exponents(terms.size());
int rightHandSite{ 0 };
// Everything in front of X is the coefficient. Handle special case, when no digit is given
std::transform(terms.begin(), terms.end(), coefficients.begin(), [](const std::string& s) {
std::string temp = s.substr(0U, s.find('X'));
if (1 == temp.size() && !std::isdigit(temp[0])) temp += '1';
return std::stoi(temp); });
// Get all exponents
std::transform(terms.begin(), terms.end(), exponents.begin(), [](const std::string & s) {
return std::stoi(s.substr(s.find('^') + 1)); });
// Get right Hand site of equation
rightHandSite = std::stoi(equation.substr(equation.find('=') + 1));
// Show result
std::cout << "\nEquation: " << equation << "\n\nFound '" << terms.size() << "' terms.\n\nCoeffient Exponent\n";
for (size_t i = 0U; i < terms.size(); ++i)
std::cout << std::right << std::setw(9) << coefficients[i] << std::setw(10) << exponents[i] << "\n";
std::cout << "\n --> " << rightHandSite << "\n";
return 0;
}
Существует множество других возможных решений. Но, возможно, это даст вам представление о том, что вы могли бы сделать.