「コード、プログラムがわからない」ではなく、「問題の解き方」がわからない、でしょう?
ネタ元:問題としては面白い、うん。
ん???これ、大学や専門学校?高校じゃないですか?だって、問題の解き方が、ものすごく親切に問題文に織り込まれていますよ?
上の実験において,t-i(t)曲線(放電電流曲線)とt=0,i(t)=0で囲まれる部分の面積は
実験手順(1)でキャパシタに蓄えられた電気量を表しており,
この電気量Qをもとにキャパシタの静電容量Cを次のように求めることができる:
C = Q/V = Q/3 (Vは電池の電圧だから)
電流がマイクロアンペアで書かれているので,
この式からだとキャパシタの静電容量はマイクロファラド単位で求まる.
inputA.txt~inputC.txtからはt-i(t)曲線を正確に得ることはできないので,
隣り合う実験データを結んで得られる折れ線とt=0,i(t)=0で囲まれる部分の面積を計算し,
そこからキャパシタの静電容量のおおよその値を推定するプログラムを書きなさい.
静電容量 C を求めるために、C を求めるための式が書いてある。C を求めるためには Q が必要で、Q が i(t) の曲線と、t = 0, i = 0 の線からなる図形の面積であることが書かれている。また、i(t) が本来なら曲線になるべきが、実験からは直線しか得られないので、擬似的に求めると注釈してある。また、「隣り合う実験データを結んで得られる折れ線」と、注釈してある。
大学や専門学校って、ここまで親切に解き方を説明しますか?(え?「ゆとり対応」ですって?...orz)高校の専科か、高専、それも低学年じゃないかなぁ?
そういえば、がるさんところで「読解力がない」とかいう記事への突込みがあったな。あの記事は「読解力」というより「読心力」だったけど、この親子こそ、「読解力がない」だな。。。
こんなところで「考え方」とかやっても仕方ないのだけれど、問題をどう読み解くかというのは、あらゆるシステム開発につながると思うので、やってみる。
まず、親切にも、「隣り合う実験データを結んで得られる折れ線とt=0,i(t)=0で囲まれる部分の面積を計算」すると、示されています。これを、一度でもグラフに描いてみれば、ある程度目処がつけられるでしょう。
はい、これが今日のポイントです。文字を追いかけてばかりいないで、図を描いてみる。これが解決への道の、一里塚です。日本語の文字は漢字を使います。漢字は「音」だけでなく「意味」も表すため、表音文字に比べてたくさんの情報を詰め込むことができます。しかし、それでも、図によって得られる理解には及びません。表や図が描けそうな場合はまず描いてみる。そうすると、より問題を明らかにして、理解することができるでしょう。これは自分だけでなく、他人に説明するときにも有効です。
そうすると、「隣り合う実験データ」によって、台形が描かれていることがわかります。つまり、t = 0 から、i = 0 になるまでの台形の面積を足せば、Q が求められるとわかります。え?「最後は台形じゃなく、三角形だろ」ですって?上底が長さ0の台形だと考えてください。台形の面積は「(上底の長さ + 下底の長さ) × 高さ ÷ 2」です。長さ0の辺があると考えると、「(0 + 下底の長さ) × 高さ ÷ 2」で、三角形と同じになります。
大学とかなら、そうやってプロットした点から曲線を描くための式を求めろ、とか、いわれそうなんだけど、まぁ、それやるとプログラムも複雑になるから、削ったかな?
とにかく、すでに計り終わっている(これ重要)わけで、全ての点がそろっています。そろっているから計算できます。
こうやって図にすると、「辺」は観測時間での「電流」とすればよいし、「高さ」は観測時間の「間隔」ということになります。2~3度こういう図を描いておけば、後は頭の中で描けるようになるでしょう。
何事も、いっぺんに全部やろうとするから難しく思えてしまうのです。細かく分解して、することができる可能な小さい部品に分解し、ひとつずつくみ上げていけば、達成できるのです。
さて、台形の面積を積み上げればよい、ということがわかったところで、そのデータをどうやって供給するか、考えます。これは、「ファイルに書いてある」ことが示されています。問題は、そのファイルが3つあることですが、それは、まずは無視します。
げ!ずっとεπιστημηさんのエントリしか見ていなかったのですが、元の質問文を見ると、台形や三角形の面積の和として電気量を求めるとよい
とか書いてあるやん...おいおい(--;)
いやぁ~、どうしよ。「アホみたく簡単ぢゃん」に対して、「台形の面積求めるってのが、気づきにくいかもね?」って持って行こうとしたんだけど、問題文に「台形や三角形の面積の和」って書いてあるのでは、、、あはは。。。
で、なに?ファイルからの入力データの読み込み、読み込み結果の確認、静電容量の計算(台形や三角形の面積の和として電気量を求めるとよい)のそれぞれの部分は関数化して、mainから順次呼び出すようにプログラムを作ること。
ですって?はいはい。ん?「読み込み結果の確認」って、何だろ?まぁ、飛ばしちゃえ。で、ご親切にも、本当にご親切に、関数を切り分ける単位まで書いてある、と。つまり、スケルトンはできていて、本当に肉付けだけだと。
ぽあぽあ~っと、脳内コーディング。コンパイルしていません。当然、動かしていません。つか、ファイルから読み取るところ、作ってないし。。。
typedef struct experimentData {
int t;
double electricity;
} ExperimentData;
int ReadDataFromFile(char*, /*out*/ExperimentData**, /*out*/int*);
int CalcCapacitance(ExperimentData*, int, double, /*out*/double*);
int main(int argc, char** argv)
{
ExperimentData *data; // 実験データ
int count; // 実験データの数
double capacitance; // 静電容量
if (argc < 2) {
// todo: メッセージを表示
exit(-1);
}
// todo: ファイルからデータを読み込む
if (ReadDataFromFile(argv[1], &data, &count) == 0) {
// todo: ファイル読み込みエラーの処理
exit(-1);
}
// todo: データの整合性を確認する(「読み込み結果の確認」って、これ?)
// 静電容量の計算をする
if (CalcCapacitance(data, count, 3.0, &capacitance) == 0) {
// todo: 計算処理のエラー処理
// todo: data を解放
exit(-1);
}
(void) fprintf(stdout, "%lfmF\n", capacitance);
// todo: data を解放
exit(0); // む?なんで 0 なんだ?
}
int CalcCapacitance(ExperimentData* data, int count, double voltage, double* capacitance)
{
int i;
int ret = 1; // 0 = 結果を参照してはいけない
capacitance = 0.0;
if (voltage == 0.0) {
// 電圧 0V だと計算できない
return 0;
}
// 電気量を計算する
// i(t) グラフと t=0, i=0 の線の内側の面積が電気量
for (i = 1; i < count - 1; i++) {
int dt = data[i].t - data[i - 1].t;
if (dt <= 0) {
// 時間が経過していないとか、反対になっているのは、ちょっと
ret = 0;
break;
}
// 上底 = 着目中の電流値
// 下底 = ひとつ前の電流値
// 高さ = ひとつ前から着目中までの経過時間
capacitance += (data[i - 1].electricity + data[i].electricity) * dt / 2.0;
}
// 静電容量 = 電気量 / 電圧
capacitance /= voltage;
return ret;
}
投稿日時 : 2008年1月8日 21:47