今だけ人気マンガ100円レンタル特集♪

課題内容:
1.テキストファイルから数式(prefix形式)を読み取り、それを通常の数式(infix形式)に直してコンソールに出力。
2.数式内の変数xに代入する値をユーザーに求め、代入後の式の値を出力。
3.数式の微分(derivative)を求め出力。
4.2で入力された値を3の式のxと置き換え、置き換えた後の値を出力。

例としては下のようになります。
------------------------------------------------------------------
Enter file that contains the mathematical expression: formula1.txt
3*x
Enter a value for x: 4
(3*4) = 12
Derivative:((3*1) + (0*x))
Replacing x with 4 in derivative: ((3*1) + (0*4)) = 3
------------------------------------------------------------------
インプットファイル:formula1.txt
*
3
x

以下のクラスを使って問題を解かなければなりません。
・Formula.h and Formula.cpp
・Add.h and Add.cpp
・Multiply.h and Multiply.cpp
・Subtract.h and Subtract.cpp
・Divide.h and Divide.cpp
・Exponent.h and Exponent.cpp
・Constant.h and Constant.cpp
・Variable.h and Variable.cpp
(Formulaクラス以外の7つのクラスはFormulaクラスを継承し、Formulaクラスは下記の4つの仮想関数をもつものとします。)
・virtual void print()
・virtual void print(int)
・virtual void derivative()
・virtual int evaluate(int)
(他の7つのクラスはそれぞれコンストラクタ、デストラクタ、print()、derivative()、evaluate()を持ちます。 )


一応今までに書いたコードを載せておきます。恥ずかしながらinfix形式に直して出力するところまでしかできていません。どうぞどなたかお力添えをお願いたします。

#include <deque>
int main()
{
ifstream inFile;
inFile.open("input2.txt");
deque<char> oprt;
deque<char> other;
if (!inFile.is_open()) {throw "Failed opening file.";}
else
{
while (!inFile.eof())
{
char in;
inFile>>in;
if (in == '+' || in == '-' ||in == '*' || in == '/' || in == '^') oprt.push_front(in);
else other.push_back(in);
}
other.pop_back();
}

deque<char>::iterator it1 = oprt.begin();
deque<char>::iterator it2 = other.begin();
while (1)
{
if (it1 == oprt.end() && it2 == other.end()) break;
else
{
if (it2 != other.end()) {cout<<*it2<<" "; it2++;}
if (it1 != oprt.end()) {cout<<*it1<<" "; it1++;}
}
}

inFile.close();
return 0;

このQ&Aに関連する最新のQ&A

A 回答 (3件)

ついでだけど, 読み込んだ結果は Formula * にするだろうから, 「入力ストリームから読み込んで Formula * を返す」関数を作っておくべきでしょう.


再帰的に読み込むなら必須だし, そうでなくても「プログラムを読みやすくする」意味で関数にしておくべし.
    • good
    • 0

コンストラクタの仕様がわからんとか「derivative の返り値が void なのはなんか変」とかは思うんだけど, それはともかく読み込みは再帰的にやるのが簡単だと思う.


1. 1文字読み込んでみて
2. 演算子ならそのあとに 2つの被演算子があるはずなのでそれらを再帰的に読み込む
3. 演算子でなければ変数か定数なので適切なオブジェクトを作る
という構造で OK のはず.
    • good
    • 0
この回答へのお礼

なるほど。。再帰をつかうと簡単なのですね。試してみます。
どうもありがとうございました。

お礼日時:2009/05/07 00:54

読み込みは


while (!inFile.eof())
{
  char in = 0;
  inFile>>in;
  if ( in != 0 ) {
    if (in == '+' || in == '-' ||in == '*' || in == '/' || in == '^') oprt.push_front(in);
    else other.push_back(in);
  }
}
// other.pop_back();
とすれば pop_backは不要 ... 読み込み失敗時のpush_backをしないようにする

表示部は otherが無くなるまでループすればいいので
for( ; it2 != other.end(); it2++ ) {
  cout << *it2;
  if ( it1 != oprt.end() ) {
    cout << *it1;
    it1++;
  }
}
といった具合では ...
    • good
    • 0
この回答へのお礼

回答どうもありがとうございます。
試してみます。

お礼日時:2009/05/07 00:53

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q(C言語)ニュートン法のプログラムの為の数値微分

Visual StudioでC言語のプログラムを書く課題が出されたのですが、ニュートン法のプログラムを書くために
関数f(x)=3+ 2x + {2x - cos^2(x) - sin(x)} / {x^2 + cos(x^2) + sin^3(x^3)}
という関数を微分しなければいけません。担当の先生からは、関数が複雑で普通に微分するのは難しいから
f'(x) ≒ {f(x+Δx) - f(x)} / Δx を、Δx=0.0001として数値微分しなさいと指定されています。
どのように計算すればいいのでしょうか?
Δxにそのまま代入するだけではとても計算できそうにないです。

Aベストアンサー

#include<stdio.h>
#include<math.h>

//#define MAX_ITERATIONS 50  /* ニュートン法の最大反復回数 */
#define MAXITERATIONS 50 //上だとエラーになるのでこう書き換えた

double function(double x);
double dFunction(double x);
double newtonSolver(double initValue, double tolerance);

void main(){
double x;
x = newtonSolver(4.0, 0.001); /* 1つ目の引数が初期値、2つ目は許容誤差 */
printf("function(%f) = %f\n", x, function(x)); // 0になるかのチェックだよ
}

/* ニュートン法による解の計算 */
/* initValue x の初期値 */
/* tolerane 許容誤差 */
double newtonSolver(double initValue, double tolerance){
double x = initValue; /* 初期値の代入 */
int counter; // C言語だとこうしないといけない

printf("starting Newton solver...\n");
printf("step\tx\t\tcorrection\t\n");

/* for (int counter = 0; counter < MAXITERATIONS; ++counter){ これはC++やJavaだ */
for (counter = 0; counter < MAXITERATIONS; ++counter){
/* 求める解への修正量を求める */
double correction = -function(x) / dFunction(x);
printf("%3d\t%5f\t%f\n", counter, x, correction);
x += correction;

/* 修正量(correction)の絶対値が許容誤差(tolerance)以下だったら
解となる x を返して関数を終了する
ちなみにfabs()は絶対値を求める関数 */
if (fabs(correction) < tolerance){
printf("ans = %f\n\n", x);
return x;
}
}
/* 最大反復回数を超えた場合は、収束していないので
異常値をあらわすNot a Number (NAN)を返す */
printf("Newton solver did not converge!\n\n");
return NAN;
}

/*対象の関数*/
double function(double x){
return 3 + 2*x + (2*x - pow(cos(x),2) - sin(x)) / (pow(x,2) + cos(pow(x,2)) + pow(pow(sin(x), 3),3));
}

//関数の部分はNo.3さんからのコピー(ポリポリ)
//間違っていたら、No.3さんのせいだからね~(笑)

/* 対象の関数を微分した関数 */
double dFunction(double x){
double dx;
dx = 0.0001;
return (function(x+dx)-function(x))/dx;
}



私が動かしたプログラムはこれ↑よ。
ダメならば、上のソースプログラムをコピペして、コンパイルしろ!!

計算結果は

starting Newton solver...
step x correction
0 4.000000 -6.135696
1 -2.135696 2.833077
2 0.697381 -1.283641
3 -0.586260 -0.494514
4 -1.080774 0.095784
5 -0.984990 0.014808
6 -0.970182 0.000271
ans = -0.969911

function(-0.969911) = -0.000000

です。

#include<stdio.h>
#include<math.h>

//#define MAX_ITERATIONS 50  /* ニュートン法の最大反復回数 */
#define MAXITERATIONS 50 //上だとエラーになるのでこう書き換えた

double function(double x);
double dFunction(double x);
double newtonSolver(double initValue, double tolerance);

void main(){
double x;
x = newtonSolver(4.0, 0.001); /* 1つ目の引数が初期値、2つ目は許容誤差 */
printf("function(%f) = %f\n", x, function(x)); // 0になるかのチェックだよ
}

/* ニュ...続きを読む

Q三角関数の記述の仕方

タイトルそのまんまなんですが、三角関数はC言語ではどのように記述すればいいでしょうか?
角度にラジアン表記でπ(パイ)を使いたいんですが、その表記方法もわかりません。
僕の持っている本に載ってなかったので質問させていただきました。
よろしくお願いします。

Aベストアンサー

C言語で三角関数を使うためには、math.h をインクルードする必要があります。使い方は例えば、こんな感じです。

#define M_PI 3.14159265358979 /* 円周率 */

double x, y, theta;

theta = M_PI / 4.0;
x = cos(theta); /* sin,cos,tanの引数は弧度法の角度です。*/
y = sin(theta);

πは上記の例のように自分で定義して使ってください。

Q方程式を2分法を用いて解くプログラム

学校で出されたCプログラムの課題で、1問だけどうしても出来ない問題があるんです。
「方程式 f(x) = x2 - 2 = 0 を 2 分法を用いて解くプログラムを作成せよ。ここで、方程式 f(x) = x2 - 2 は関数として定義せよ。上位の方から 4 桁目まで正しい値が出たらループを止めるようにする。」
というものなのですが、この「2分法」というやり方もよく分かりません。
プログラムの作成方法と併せて教えて頂けると幸いです。

Aベストアンサー

こんな感じでしょうか?

#include <stdio.h>

/* 関数 f(x) */
double f(double x) {
 return x*x-2.0;
}

/* 二分法 初期値 x1<x2 と 誤差限界 eps を入力 */
double bisec(double x1, double x2, double eps) {
 double x;
 while (x2 - x1 >= eps) {
  x = (x1+x2)/2.0; /* 中点計算 */
  if (f(x1)*f(x) > 0.0) { /* 同符号か判定 */
   x1 = x;
  } else {
   x2 = x;
  }
 }
 return (x1+x2)/2.0;
}

int main(void) {
 double eps=0.00001;
 printf("%lf %lf\n",bisec(-2,0,eps), bisec(0,2,eps));

 return 0;
}

QExcelで微分をしたいのですが。。。

題意のままですが・・・(´;ω;`)ウッ…
Excelを使って微分の計算をすることは可能でしょうか・・・?
またExcelで使えるツールなどでももちろんOKです。
ご存知の方が見えましたらお助けお願いします。。。

Aベストアンサー

>エクセルを使って微分の計算をする
とはどういうことでしょうか。
たとえば、(1)y=Xの2乗の導関数のy=2Xを求めるということでしょうか。これは「数式処理」に該当し、エクセルは値を扱う(四則演算が中心)ものなので、お門違いの要求です。他のソフト(ただし原理的にどんな数式・関数に対しても求まるソフトはないようですが)を探しましょう。ただアドインという形だとプログラムを組んで何でもエクセルにぶち込めるようなので、そういう例があったとしたら、話は別です。
積分の原始関数を求めるというのも似たパターンでしょう。
そうではなくて
(2)上記の例で、導関数を、人間が!
(A)エクセルの関数式で与えてやり、
(B)またはその導関数の近似値を与える関数式を与えて
やるなら、
後はエクセルは「電卓の計算を繰り返し高速計算するような」ものですから可能と思います。
ただ1000個の数の足し算をするという風には簡単にいかないケースがあるとは思いますので、勉強がひつようでしょう。収束や近似や速度に合う条件・計算法が必要でしょうから。
y=Xの2乗の(1、1)点の接線の勾配を出すなら
2X1=2で簡単です。
微分でなくて、定積分なら数値計算法を質問する意味はあると思いますが。
エクセルは四則演算といっても初等的三角関数、対数
、行列計算、ガンマ関数などもあります。
上記は原則論ですが、エクセルは全世界の俊秀も使っているとおもわれ、いろいろな機能を付加されているかも知れないので、最低WEB照会程度はして、よく調べてください。またエクセルを入り口や出口の入力・結果表示の道具として使っているケースは多いようですから、そういうケースは「エクセルでできる」に該当しないと思います。

>エクセルを使って微分の計算をする
とはどういうことでしょうか。
たとえば、(1)y=Xの2乗の導関数のy=2Xを求めるということでしょうか。これは「数式処理」に該当し、エクセルは値を扱う(四則演算が中心)ものなので、お門違いの要求です。他のソフト(ただし原理的にどんな数式・関数に対しても求まるソフトはないようですが)を探しましょう。ただアドインという形だとプログラムを組んで何でもエクセルにぶち込めるようなので、そういう例があったとしたら、話は別です。
積分の原始関数を求...続きを読む

Qニュートン法を使って解を求めるC言語プログラム

C言語を使って y=x^2-4x のyの解をニュートン法を使って求める
プログラムを作る課題を出されたんですが、ニュートン法が良く分かっていないので、いろいろ調べたり、人に聞いたりしたところ
#include<stdio.h>
#include<math.h>
void main()
{
int counter=0;
double an,g,f,sh=0.0001;
printf("初期値を入力して下さい==>");
scanf("%ld",&an);
do{
g=(an*an)/(2*an-4);
f=2*an-4;
counter++;
}while(fabs(f)>sh);
printf("反復回数 %d 回 y=%lf \n",counter,g);
}
でプログラムがこんな感じになったんですが、結局ニュートン法がどうなのかがわかりません。 なんか微分とかやるとか言われたんですが、工業系の学校で数学の授業が無いので微分についてがわかりません。
このプログラムは、コンパイルはできるんですが、動きません。
ニュートン法についてよくわからないのでどこが間違ってるかわかりません。 ニュートン法についてできるだけ分かりやすく解説してほしいです。

C言語を使って y=x^2-4x のyの解をニュートン法を使って求める
プログラムを作る課題を出されたんですが、ニュートン法が良く分かっていないので、いろいろ調べたり、人に聞いたりしたところ
#include<stdio.h>
#include<math.h>
void main()
{
int counter=0;
double an,g,f,sh=0.0001;
printf("初期値を入力して下さい==>");
scanf("%ld",&an);
do{
g=(an*an)/(2*an-4);
f=2*an-4;
counter++;
}while(fabs(f)>sh);
printf("反復回数 %d 回 y=%lf \n",counter,g);
}
でプログラムがこんな感...続きを読む

Aベストアンサー

ニュートン法を理解するには、せめて微分の初歩の初歩は理解して下さい。
とりあえず、必要なところだけ。

y=x^2-4x
の解をもとめるには、次のようにします。
計算途中の近似解をa(n)とすると、それを元に得られる、より精度の良い近似解a(n+1)は、
a(n+1)=(a(n)*a(n))/(2*a(n)-4)
として求められます。(ニュートン法の理論から)
これを繰り返していって、
|a(n+1)-a(n)| < 0.0001
となったときに、十分精度の良い解が得られたと判断し、計算を終了します。
(計算終了の閾値0.0001は提示されたプログラムから取りました。)

プログラムの間違いは、下記の2点。
誤:scanf("%ld",&an);
正:scanf("%lf",&an);

誤:f=2*an-4;
正:f=g-an; an=g;

上記を修正し、初期値が2より大きい場合は4.000000が、初期値が2未満のときは
0.000000が求められることを確かめて下さい。

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

QC言語 配列の長さの上限

C言語で配列Array[N]の長さNの上限っていくらなんでしょうか?
もし可能なのであれば上限を2147483647にしたいのですが、方法を教えてください。

Aベストアンサー

そもそもWindowsの32bit版はアプリが仮想メモリ空間を2GBしか使えません。2GBを超えるには64bit版が必要です。
たとえ64bit版OSだとしても添え字が2147483647って、単純なintの配列だとしても4x2147483647=8GB必要ですね。実メモリ16GBとかのPCを用意しますか?
そもそも配列で2147483647個必要なアルゴリズムに問題ありだと思います。

QC言語で-23乗を取り扱うには

C言語でボルツマン定数

1.38*10^(-23)

を取り扱いたいと思っています。

k = 1.38/pow(10, 23);
あるいは
k = 1.38/100000000000000000000000;

としても、コンパイルはできますが実行したときに
『1.#INF00』
という表示(マイナス無限大?)が出てしまいます。

このようにとても小さな定数をC言語で扱う場合、
どのようにすればよいのでしょうか?

よろしくお願いします。

Aベストアンサー

#include <stdio.h>

int main(void)
{
double k = 1.38e-23;

printf("ボルツマン定数K=%e\n", k);
return 0;
}

Qc++ cmathとmath.h

お世話になります。c++を始めたばかりの者です。

cmathとmath.hの二つのヘッダーファイルは、それぞれ何をするときに使用するのでしょうか。
教本やネットを調べてもイマイチ理解できず、質問させていただきました。

ご回答よろしくお願い致します。

Aベストアンサー

どちらも数値演算をする際に使用するヘッダファイルです。

どちらを使用すべきかは、C言語では<math.h>の一択です。

C++ではどちらも使えます。というか、<cmath>は<math.h>をラップしていて結局同じ関数が呼ばれます。
では何が違うかというと、<cmath>をインクルードした時の数値演算関数はstd名前空間内に所属するようになります。それに対して、<math.h>をインクルードした時の数値演算関数はグローバル関数になります。


人気Q&Aランキング