3

簡単に聞こえるが、プログラムしようとしたときにそのように見えないことを行う方法について、誰かが情報や経験を持っているかどうか知りたいです。アイデアは次のとおりです。たとえば、「2*x = 10」などの方程式を含む文字列を指定します (これは単純ですが、sqrt(54)*35=x^2 などのように非常に複雑になる可能性があります)。 on....) そして、プログラムは x = 5 を返し、おそらく彼がそこにたどり着いた方法のログを提供します。

これは実行可能ですか?もしそうなら、誰かがリードを持っていますか? 情報については、PHP で同じことを行うこのサイト ( http://www.numberempire.com/equationsolver.php ) がありますが、オープン ソースではありません。

助けてくれてありがとう!

4

7 に答える 7

3

これを「構文解析」といい、計算機科学はすでにこの問題を解決していますが、完全に理解するまでは簡単ではありません。この問題を解決する方法を説明するコンピューター サイエンス分野全体があります。C では、入力の文法を定義し (優先順位規則が含まれている可能性があります)、入力に対して字句解析を実行し、結果を解析して、最後に解析ツリーを評価する必要があります。

ただし、Ruby などの言語では、文字列操作が非常に完全にサポートされており、非常に強力な実行時能力があるため、次のような 1 行のコードで問題を解決できます。

puts(eval($_)) while gets

はい、それはあなたが求める以上のものをカバーします。

于 2010-05-16T18:44:41.557 に答える
2

まず、入力として使用できる方程式の種類を適切に定義する必要があります。次に、方程式を表す適切な抽象化 (多項式クラスなど) を作成する必要があります。より複雑な式を使用する場合は、数値式のツリーを使用します。式をプレフィックス表記に変換する適切なルールがあれば、解析は非常に簡単です。スタックを使用すると、評価が簡単になります。人工木または多項式を取得したら、変換を実装して変数を計算できます。

于 2010-05-16T18:39:21.047 に答える
1

1 つの訂正: これは通常、複数の方程式と未知数の行列を意味する線形代数ではありません。

あなたの例は確かに複雑ではありません。

必要なのは、単純な式の文法とパーサーです。方程式を解析して抽象的な構文ツリーにし、ツリーをたどって評価します。

Java を書いていた場合は、次のようになります。別の例はsymjaです。おそらく、C++ 用に独自のコードを作成するのに十分なインスピレーションになるでしょう。

また、Mathematica と Wolfram の Alpha を調べることもできます。Stephen Wolfram は、世界最高の数学者およびコンピューター科学者の 1 人です。彼は、自分で書くのではなく、再利用できる利点をたくさん持っています。

「解決する」とは何を意味するのか、何を返すと期待するのかを定義する必要があります。

記号解と数値解があります。どちらのことですか?どちらも同じように有効ですが、異なります。答えに応じて、さまざまなテクニックを適用します。

別のポイント: 方程式のタイプに大きく依存する方程式を「解く」ための多くの手法があります。あなたが私に何かを与えるなら、私f(x) = 0はニュートンの方法のような根を見つけるアルゴリズムについて考えます。常微分方程式を教えてくれたら、ルンゲクッタを使った代入法や数値積分を試してみようかな。偏微分方程式を教えていただければ、有限差分法、有限要素法、または境界要素法を適用できます。(楕円偏微分方程式、放物型偏微分方程式、および双曲型偏微分方程式から始めないでください。)

ポイントは、あなたの質問は非常に一般的であり、答えはあなたが何をしようとしているのかに大きく依存するということです. 詳細が役立つ場合があります。

于 2010-05-16T18:37:10.107 に答える
1

一般に、式を何らかの内部表現に解析する必要があります。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++ で実装します。

于 2010-05-17T16:46:34.657 に答える
1

SymPy で C (または C++) コードにリンクし、それを使用して方程式を解くことができます。

IIRC、SymPyにはそのような機能があります。さらに、入力文字列を Python 内で使用可能な方程式に操作し、それを SymPy に渡して解く方が簡単なはずです。

于 2010-05-16T18:44:52.710 に答える
1

方程式が複雑になる場合、それは確かに数行の C/C++ コードではありません。

線形方程式については、Linear Algebra Books で説明されている方法の 1 つをシミュレートする必要があります。そのコードは十分に小さいです。

于 2010-05-16T18:36:26.230 に答える
1

問題には 2 つの部分があります。方程式の解析と、それらを記号的に解くことです。他の回答がすでにそのトピックを十分にカバーしているため、最初のものについてはあまり言いません。私の個人的な推奨事項は、プレフィックス表記の式の単純な再帰降下パーサーを作成することです。

解析的に方程式を解く 2 番目の部分は、注意が必要です。一般的に言えば、解析解を見つけるための標準的な方法が存在する特別なクラスの方程式があります。

  • 線形方程式系: 任意の直接線形ソルバー。手順を明示的に示したい場合で、方程式や未知数の数が少ない場合は、非ピボット ガウス消去法や Cramer の法則などの単純なものをお勧めします。
  • 多項式の方程式: 変数置換後、単一の多項式の根を見つけることと同等です。これらの次数が 4 以下の場合、正確な解の式があります。注: 3 度と 4 度の場合、これらの式は適切ではありません。
  • 有理係数をもつ多項式系の有理解: 上記のように変数置換を行います。次に、合理的なゼロテストを使用したブルートフォース。
  • 他の種類の方程式: 頑張ってください。より複雑な [システムの] 非線形方程式について、数値 (非解析的) 解で解決できる場合は、ニュートン法を調べてください。
于 2010-05-16T19:04:33.723 に答える