Вопрос

Я хотел бы знать, есть ли у кого-нибудь информация или опыт о том, как сделать что-то, что звучит просто, но не выглядит так при попытке запрограммировать.Идея заключается в следующем:дайте строку, содержащую уравнение, например:Например, «2*x = 10» (это просто, но может оказаться очень сложным, например sqrt(54)*35=x^2;и так далее....) и программа вернет x = 5 и, возможно, выдаст лог того, как он туда попал.

Это осуществимо?Если да, есть ли у кого-нибудь зацепка?Для информации есть этот сайт(http://www.numberempire.com/equationsolver.php), который делает то же самое в PHP, но не имеет открытого исходного кода.

Спасибо за любую помощь!

Это было полезно?

Решение

Это называется «расставание», и хотя компьютерная наука уже решила эту проблему, все вообще не просто, пока вы не поймете ее полностью. Есть целая компьютерная дисциплина, которая описывает, как решить эту проблему. В C вы должны определить грамматику вашего ввода (возможно, с правилами приоритета в нем), затем выполнить лексический анализ на вашем входе, то разбираться Результат и, наконец, оцените дерево вашего разбора.

На таких языках, как Ruby, однако, потому что у вас такая тщательная поддержка для манипуляций строки и потому, что у вас такое огромное время выполнения, вы можете решить вашу проблему с помощью одной строки кода, как так:

puts(eval($_)) while gets

Да, это будет охватывать больше, чем вы спрашиваете.

Другие советы

Во-первых, вы должны правильно определить, какие уравнения вы можете иметь в качестве ввода. Затем вы должны создать хорошую абстракцию для представления уравнения, например, полиномиального класса. Когда вы хотите использовать более сложное выражение, выйдите на дерево для численных выражений. Разборка может быть довольно простым, если у вас есть хорошие правила, чтобы преобразовать выражение в префиксную запись, тогда оценка легко использует стеки. После того, как у вас есть артититметические деревья или полиномы, вы можете реализовать преобразования для вычисления переменной (ы).

Если уравнения получают комплекс, это, безусловно, не будет мало строк кода C / C ++.

Для линейных уравнений вам придется имитировать один из методов, описанных в линейных книгах алгебры. Кодекс этого недостаточно.

Вы можете попробовать связать SymPy с вашим кодом C (или C++) и использовать его для решения ваших уравнений.

IIRC, SymPy имеет такую ​​функциональность.Кроме того, должно быть проще преобразовать входную строку в полезное уравнение внутри Python, а затем передать его в SymPy для решения.

Для вашей проблемы состоит из двух частей: разбирая уравнение (ы) и решать их символически. Я не собираюсь много говорить о первой, так как другие ответы уже охватывали эту тему хорошо; Моя личная рекомендация будет написать простой рекурсивный анализатор спуска для выражений в префиксе обозначения.

Вторая часть, решение уравнений, аналитически, будет сложно. Вообще говоря, существуют специальные классы уравнений, для которых существуют стандартные методы, чтобы найти аналитическое решение:

  • Системы линейных уравнений: любой прямой линейный раствор. Если вы хотите показать шаги явно, и количество уравнений / неизвестных мало, я бы порекомендовал что-то простое, как неповторимый гауссовский ликвидация или правило Крамера.
  • Система полиномиальных уравнений: эквивалент, после переменной замены, на нахождение корней одного полинома. Если они имеют степень <= 4, есть формулы для точных решений. NB: Для степени 3 и 4 эти формулы не приятны.
  • Рациональные решения системы полиномиальных уравнений с рациональным коэффициентом: выполнение переменной замены, как указано выше. Затем грубую силу, используя рациональный нулевой тест.
  • Другие виды уравнений: удачи. Для более сложных [систем] нелинейных уравнений, если вы можете согласиться на численные (неаналитные) решения, посмотрите в метод Ньютона.

Одна коррекция: это не линейная алгебра, которая обычно означает зацикливания нескольких уравнений и неизвестных.

Ваш пример конечно не сложный.

То, что вам нужно, это простое выражение грамматики и парсера. Разбирайте уравнение в абстрактное синтаксическое дерево и пройдите дерево, чтобы оценить его.

Если вы пишете Java, это может выглядеть это. Отказ Другой пример есть Symja. Отказ Возможно, вам будет достаточно вдохновения для вас, чтобы придумать свои собственные для C ++.

Вы также можете посмотреть на альфа Mathematica и Wolfram. Стивен Вольфрам - один из лучших в мире математиков и компьютерных ученых. У него много вещей, которые вы могли бы использовать хорошее преимущество, а не писать его самостоятельно.

Вам придется определить, что вы подразумеваете под «решаем» и то, что вы ожидаете, чтобы вернулись.

Существуют символические решения и численные решения. Какой из них вы имеете в виду? Оба одинаково действительны, но они отличаются. Вы будете применять разные методы в зависимости от вашего ответа.

Еще один момент: есть много техник для «решения» уравнений, которые сильно зависят от типа уравнения. Если вы дадите мне что-то вроде f(x) = 0 Я думаю о алгоритмах roote поиска, как метод Ньютона. Если вы дадите мне обычное дифференциальное уравнение, я мог бы попробовать метод замещения или численную интеграцию с использованием Рунге-Кутты. Если вы дадите мне частичное дифференциальное уравнение, я могу применить конечную разницу, конечный элемент или методы граничных элементов. (Не запускайте меня на эллиптические, параболические и гиперболические PDE.)

Дело в том, что ваш вопрос очень универсален, и ответ очень зависит от того, что вы пытаетесь сделать. Более деталь может помочь.

В общем, вам придется проанализировать выражение и получить какое-то внутреннее представление.Во многих книгах по линейной алгебре предлагается использовать матрицы (или std::vector) для представления коэффициентов.Показатель степени определяется его положением в векторе.

Так, например, выражение:

 2 + 3x + 5x^2

Может быть представлено в виде массива или std::vector:

std::vector<int> expression;
expression[0] = 2; // 2 * x ^ 0
expression[1] = 3;
expression[2] = 5;

Написание оценочной функции становится тривиальной задачей и оставляется в качестве упражнения для читателя.

Решение нескольких уравнений становится более сложным.Для этого существуют существующие библиотеки и алгоритмы.Поиск в Google должен дать что-то хорошее.:-)

Я предлагаю начать с простых терминов и создать для этого синтаксический анализатор.Как только это заработает, вы можете изменить синтаксический анализатор, чтобы он также принимал имена функций.

Если вы пытаетесь упростить выражение, в котором члены находятся по обе стороны =, просто запишите шаги, которые вы обычно предпринимаете при решении вручную.Попробуйте несколько разных уравнений, чтобы сформулировать некоторые правила.Теперь реализуйте эти правила на C++.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top