ネタ元 → やれやれ
「放電曲線を用いたキャパシタの静電容量の推定」
ファイルinputA.txt,inputB.txt,inputC.txtは,次に示すキャパシタ(コンデンサ)の放電に関する実験のデータである:
(1) 最初にキャパシタを電池(3V)に接続して充電しておく.
(2)充電されたキャパシタを抵抗などに接続すると,
キャパシタの+極板から-極板に電流が流れ出す(放電する).
(3)(2)で接続した瞬間,およびそこから5秒経つごとに電流計を見て,流れる電流を記録する.
(4)放電しきるまで(電流計の読み値が0になるまで)記録をとる.
どのファイルにも,ファイルの各行には左から順に
「放電開始からの経過時間(秒)」「電流計の読み値(マイクロアンペア)」
という2つの数値が書かれている.
上の実験において,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で囲まれる部分の面積を計算し,
そこからキャパシタの静電容量のおおよその値を推定するプログラムを書きなさい.
inputA.txt
0 91
5 46
10 23
15 12
20 6
25 3
30 1
35 1
40 0
inputB.txt
0 91
5 66
10 48
15 35
20 25
25 18
30 13
35 10
40 7
45 5
50 4
55 3
60 2
65 1
70 1
75 1
80 1
85 0
inputC.txt
0 91
5 78
10 67
15 58
20 50
25 43
30 37
35 31
40 27
45 23
50 20
55 17
60 15
65 13
70 11
75 9
80 8
85 7
90 6
95 5
100 4
105 4
110 3
115 3
120 2
125 2
130 2
135 2
140 1
145 1
150 1
155 1
160 1
165 1
170 1
175 0
シャレで解いてみた
// trial.cpp
#include <iostream>
#include <fstream>
#include <utility>
#include <vector>
#include <iterator>
typedef std::pair<int,int> record;
namespace std {
std::istream& operator>>(std::istream& stream, record& rec) {
return stream >> rec.first >> rec.second;
}
}
int main(int argc, char* argv[]) {
for ( int i = 1; i < argc; ++i ) {
std::ifstream stream(argv[i]);
std::vector<record> data((std::istream_iterator<record>)(stream), std::istream_iterator<record>());
double sum = 0;
for ( int i = 0; i < data.size()-1; ++i ) {
sum += (data[i].second + data[i+1].second)*(data[i+1].first - data[i].first)/2.0;
}
std::cout << sum / 3.0 << std::endl;
}
}
実行結果
>trial inputA.txt inputB.txt inputC.txt
229.167
475.833
999.167
アホみたく簡単ぢゃん