1 名前:デフォルトの名無しさん mailto:sage [2006/01/12(木) 00:45:25 ] 教育用(?)プログラムPascalの宿題をやって頂くスレ ■丸投げOK ■全く分かってない阿呆も放置しないで優しく対応 ■他言語はよそ逝け( ゚Д゚)ゴルァ ■DelphiもTurbo Pascalも完全対応 【本家】 www.borland.co.jp/delphi/ 【前スレ】 pc8.2ch.net/test/read.cgi/tech/1089719714 【関連スレ】 くだすれDelphi(超初心者用)その15 pc5.2ch.net/test/read.cgi/tech/1087823906/l50 Pascal の初心者用の質問・相談所 pc5.2ch.net/test/read.cgi/tech/1009903617/l50 【Delphi初心者】今から始めるDelphi Part01 pc5.2ch.net/test/read.cgi/tech/1062422335/l50
110 名前:デフォルトの名無しさん mailto:sage [2006/02/05(日) 20:19:47 ] >>108 とりあえず作ってみた。 www.uploda.org/uporg304927.lzh.html ・入力のエラーチェックはしていない。 ・ FiveVector1→A FiveVector2→B FiveVectorSum→C hoeee→D という対応になってるんで、必要ならテキスト置換でも使って変換してくだちい。
111 名前:デフォルトの名無しさん mailto:sage [2006/02/05(日) 20:21:21 ] 111
112 名前:105 mailto:.. [2006/02/05(日) 21:19:38 ] >>107 ありがとうございます。ご指摘の通り直したら動きました。 ところで procedure swap(var a, b: integer); (* var で書き換え可能にする *) とありますが、varをつけるとプログラム本文のところで別の文字を使って使える ということですか? なんか実引数とか仮引数とかがわかってないことを見せつける質問ですいませんorz
113 名前:デフォルトの名無しさん [2006/02/06(月) 02:31:16 ] ハローパスカル始めることにしたから、よろしく。
114 名前:デフォルトの名無しさん mailto:sage [2006/02/06(月) 18:53:02 ] >>112 program none(output); var a,b:integer; procedure add(var a,b:integer); begin a := a + 1; b := a + 2; end; begin a:=2; b:=3; add(a,b); writeln(a,b:2); end. ってしたら最終的にaが3で、bが5になってる。 procedure add(a,b:integer); だったらadd(a,b)が実行されても値は変化しない。つまりaが2で、bが3。
115 名前:デフォルトの名無しさん mailto:sage [2006/02/06(月) 19:09:04 ] それにしても暇だ。 大学一年生にもできそうでちょっと難しいような宿題が投下されないだろうか。
116 名前:774RR mailto:sage [2006/02/06(月) 19:31:50 ] >115 じゃあCASLのアセンブラと仮装機械w
117 名前:デフォルトの名無しさん mailto:sage [2006/02/06(月) 19:50:04 ] d 最初見たとき言葉遣いとhoeeeにうけましたw
118 名前:115 mailto:sage [2006/02/06(月) 22:56:00 ] >>116 調子こいてました(>< でも単純に機械語に翻訳するだけならなんとかなるのだろうか。 そこからプログラムを動かすってのが明らかに不可能です 本当にありがとうございました。
119 名前:デフォルトの名無しさん mailto:sage [2006/02/07(火) 02:24:54 ] みんなのところもポインタで逆ポーランドの電卓つくるのがゴールかな?
120 名前:デフォルトの名無しさん [2006/02/07(火) 05:03:24 ] >>119 は?バカ?
121 名前:デフォルトの名無しさん mailto:sage [2006/02/07(火) 05:33:32 ] >>119 え?このスレってそんなレベル?
122 名前:デフォルトの名無しさん mailto:sage [2006/02/07(火) 08:50:04 ] 逆ポーランドってなんだ?
123 名前:デフォルトの名無しさん mailto:sage [2006/02/07(火) 09:51:23 ] あっはっはっはw
124 名前:774RR mailto:sage [2006/02/07(火) 12:16:18 ] 逆ポーランドなつかすいな。 HPの電卓もかっこよかたな。 1 ENTER 2 + 3 * 4 - ....
125 名前:デフォルトの名無しさん [2006/02/07(火) 13:29:25 ] ポインタをつかって逆ポーランドの電卓をつくってください。 識者の方どうかおねがいします(><)
126 名前:デフォルトの名無しさん mailto:sage [2006/02/07(火) 17:59:15 ] 電卓って?標準入力で入力していいのか?
127 名前:774RR mailto:sage [2006/02/07(火) 18:34:57 ] 手抜きで標準入力、文字列から数への変換も手抜きだ。 TP互換環境なら走るだろう。その壱 Program Enjoy2chCalc; const MaxNplus1 = 5; MaxN = 4; type pstack = ^stackitem; stackitem = record data : real; next : pstack end; var stack : pstack; s : string; r : real; i : longint; toend : boolean; procedure push(r : real); var s : pstack; begin new(s); s^.data := r; s^.next := stack; stack := s end;
128 名前:774RR mailto:sage [2006/02/07(火) 18:36:15 ] procedure pop(var r : real); var s : pstack; begin if stack <> nil then begin s := stack; r := s^.data; stack := s^.next; dispose(s) end else writeln('Stack underrun.') end; procedure calc(opr : char); var r1, r2 : real; begin pop(r2); pop(r1); case opr of '+' : r2 := r1 + r2; '-' : r2 := r1 - r2; '*' : r2 := r1 * r2; '/' : r2 := r1 / r2 end; push(r2) end;
129 名前:774RR mailto:sage [2006/02/07(火) 18:38:30 ] procedure disp; begin if stack<>nil then writeln('>>', stack^.data) else writeln('Stack underrun.') end; procedure initstack; begin new(stack); stack^.data := 0; stack^.next := nil end; procedure allclear; var s : pstack; begin while stack<>nil do begin s := stack.next; dispose(stack); stack := s end; initstack end;
130 名前:774RR mailto:sage [2006/02/07(火) 18:39:31 ] begin initstack; toend := false; repeat disp; write('ENTER Number, +-*/, q-quit, c-clear, a-AC : '); readln(s); if (length(s) = 1) and (s[1] in ['+','-','*','/','q','c','a']) then case s[1] of '+','-','*','/' : calc(s[1]); 'c' : pop(r); 'a' : allclear; 'q' : toend := true end else begin val(s, r, i); push(r) end until toend; allclear; dispose(stack) end.
131 名前:774RR mailto:sage [2006/02/07(火) 18:43:26 ] 1 2 + 3 4 + * ... って感じに入力していくと逆ポな計算機になるよ。 スタックを線形リストで表現してるのが一応演習課題に則ってる。 本当なら、文字列→数の変換もスタックを使うんだが、めんどい。 そこまですると、電卓の+/-キー(符号反転キー)が二項演算子の-キーと 分かれている理由がよく理解できる。
132 名前:デフォルトの名無しさん mailto:sage [2006/02/07(火) 18:44:36 ] procedure allclear; var s : pstack; begin while stack<>nil do begin s := stack.next; dispose(stack); stack := s end; initstack end; s := stack.next; じゃなくて s := stack^.next; じゃない?
133 名前:774RR mailto:sage [2006/02/07(火) 18:45:30 ] いけねえ、最初のconstは見なかった事にしてくれ。 前回投稿した消し残りだw
134 名前:774RR mailto:sage [2006/02/07(火) 18:47:19 ] >132 その通りだけど、何でコンパイルできたんだろうw 拡張構文なのかコンパイラのバグかww
135 名前:デフォルトの名無しさん mailto:sage [2006/02/07(火) 22:56:20 ] めちゃくちゃ初心者なのですが・・・。 問題聞いてもらってもよろしいでしょうか?
136 名前:135 mailto:sage [2006/02/07(火) 23:04:50 ] 一応問題を書かせて頂きます。 1 一方向リストの中のp番目とNEXT(p)番目の位置の要素を交換するプログラムを 手続きを用いて書け。 関数NEXTの定義:リストLで位置pの直後の位置を返す関数 とありますが、NEXTという関数はPascalに標準であるのでしょうか? 私の使っているCPad for free pascalだとないと言われるのですが・・。
137 名前:デフォルトの名無しさん mailto:sage [2006/02/07(火) 23:53:23 ] 無いんじゃない?
138 名前:デフォルトの名無しさん mailto:sage [2006/02/07(火) 23:57:04 ] >>137 ですよね・・。 ということは、自分でNEXT関数を自分で定義しろということですか?
139 名前:デフォルトの名無しさん mailto:sage [2006/02/08(水) 00:02:10 ] いや、俺もそんな詳しくないけど聞いたことはないよね。 一方向リストってどういう構造なん? ポインタで繋いでるなら別段難しいことはないと思うんだけど。
140 名前:デフォルトの名無しさん mailto:sage [2006/02/08(水) 00:05:31 ] >>139 ポインタを使ったリスト構造のことだと思います。
141 名前:デフォルトの名無しさん mailto:sage [2006/02/08(水) 00:16:52 ] type list = ^listcell listcell = record e : element; point : listCell; end; var p : list; みたいな感じに定義してlistcell型の要素が繋がってるんなら、たとえばp^.pointが pの要素の次の位置を指しているんじゃないの? なんだかいまいち俺には分からないんだ。 問題を全部書いてくれれば分かるかもしれない。 あれで全部?
142 名前:デフォルトの名無しさん [2006/02/08(水) 00:24:02 ] 双方向じゃないやつだな<一方向
143 名前:デフォルトの名無しさん mailto:sage [2006/02/08(水) 00:27:39 ] えっと、あれで全部です・・・。 e:elementってelementってどういう変数か知りませんが、要素って 名前とかじゃだめですかね? type list=^listcell listcell=record name:string[10]; id:integer; pointer:list end; var init,current:list; datname,datid:string[10]; こんな感じでもいいかな?
144 名前:デフォルトの名無しさん mailto:sage [2006/02/08(水) 00:28:28 ] >>142 じゃあ、ポインタとはまた違うものだってことでしょうか? まったく習っていないのでわかりません。
145 名前:デフォルトの名無しさん mailto:sage [2006/02/08(水) 00:29:32 ] type list=^listcell listcell=record name:string[10]; id:integer; pointer:list end; var init,current:list; datname:string[10]; datid:integer; に訂正
146 名前:141 mailto:sage [2006/02/08(水) 00:40:57 ] そっから new(init); new(current); init^pointer := current; みたいな感じで繋げていくんだよな? そのあと値を入れていったとする。 >1 一方向リストの中のp番目とNEXT(p)番目の位置の要素を交換するプログラムを >手続きを用いて書け。 >関数NEXTの定義:リストLで位置pの直後の位置を返す関数 ってことだけど、例えばp=1番目の直後の位置ってのはこの例でいくと init^.pointerが指してるもののことじゃないの? あと交換するだけなら要素の内容をレコード型変数かなにかに一旦格納して 入れ替えればいいんじゃないかと思うんだけど、どのあたりを俺は勘違いしているのか。
147 名前:デフォルトの名無しさん mailto:sage [2006/02/08(水) 00:48:50 ] >>146 > そっから > new(init); > new(current); > init^pointer := current; > みたいな感じで繋げていくんだよな? > そのあと値を入れていったとする。 この部分はわかります。 next関数に関してですが、p=1の場合と最後の時、それから途中の場合で 場合わけしなければいけないと思うのですが、 入れ替える位置というのが名前とか、idだとできると思うんですがこの問題の場合 p番目といわれるとわかりません・・・。
148 名前:デフォルトの名無しさん mailto:sage [2006/02/08(水) 00:51:39 ] あ、while current^.pointer <> nil do begin でまわしてるときに、 n:=n+1していけばいいのかな?
149 名前:141 mailto:sage [2006/02/08(水) 00:59:43 ] n := n + 1; でいいだろうね。 それとnext関数を最初と最後で場合わけしないといけないってことだけど、 最初と最後になにも入ってないダミーセルを配置しておけば例外処理を 行わなくてもできるんじゃない? つまり実際に値を格納しておくものよりも二つぶん多めにnewしとく。
150 名前:デフォルトの名無しさん mailto:sage [2006/02/08(水) 01:19:17 ] >>149 ダミーセルをつくるのはたぶんだめっていわれます。
151 名前:デフォルトの名無しさん mailto:sage [2006/02/08(水) 01:57:34 ] とりあえず、リストの作成と書き出しをやってみましたが、終了条件を'end'にしているのに endで終わらない・・・。 var init,current:list; datname:string[10]; datid:integer; begin new(init); current:=init; write('名前を入力してください'); readln(datname); write('IDを入力してください'); readln(datid); while datname <> 'end' do begin current^.name:=datname; current^.id:=datid; new(current^.pointer); current:=current^.pointer; write('名前を入力してください: '); readln(datname); write('IDを入力してください: '); readln(datid); end; current^.pointer:=nil; {リストの書き出し} current:=init; while current^.pointer <> nil do begin write(current^.name,' ',current^.id); current:=current^.pointer end; writeln end.
152 名前:デフォルトの名無しさん mailto:sage [2006/02/08(水) 02:11:37 ] なんかいろいろセミコロンが抜けてるように見えるんだけど
153 名前:デフォルトの名無しさん mailto:sage [2006/02/08(水) 02:12:25 ] 直りました。 var init,current:list; datname:string[20]; datid:integer; begin new(init); current:=init; write('名前を入力してください: '); readln(datname); current^.name:=datname; while datname <> 'end' do begin write('IDを入力してください: '); readln(datid); current^.id:=datid; new(current^.pointer); current:=current^.pointer; write('名前を入力してください: '); readln(datname); current^.name:=datname end; current^.pointer:=nil; {リストの書き出し} current:=init; while current^.pointer <> nil do begin write(current^.name,' ',current^.id,' '); current:=current^.pointer end; writeln end.
154 名前:デフォルトの名無しさん mailto:sage [2006/02/08(水) 02:14:15 ] 問題はここからですね。入れ替える位置pを入力して、p番目の要素とp番目の次の 要素を入れ替えなさい。
155 名前:デフォルトの名無しさん mailto:sage [2006/02/08(水) 12:31:22 ] できない・・・。currentの前を指すpreviousを用意して currentとpreviousのpointerを入れ替えればできるか思ったのですが 無限ループになってしまいます。 削除と挿入ならできるのに・・。
156 名前:774RR mailto:sage [2006/02/08(水) 12:32:36 ] この手の課題でリストの頭と尻尾にダミーをいれておいて、 必ず3個以上の要素が存在するようにするのは 極普通のプログラミングテクニックで、やらないほうが変だと思うが… 「次」を示すフィールドがnextだとするね。 p-1番目の要素を見つける所から始める。 これはwhile文で頭から律儀に数えるしかない。 その上で、 ppred ← p-1番目の要素を指すポインタ pp:=ppred^.next ← p番目の要素を指すポインタ psucc:=pp^.next ← p+1番目の要素を指すポインタ をまずやっとく。 pwork := psucc^.next; ppred^.next := psucc; psucc^.next := pp; pp^.next := pwork; これでppred->psucc->pp->元のpsuccの次って順序になった。 psucc, pp, ppred, pworkは全部局所変数でおけ。 >146 record型のデータの部分がでかい場合、コピするのにマシンサイクルを 使い過ぎる。簡単に張り替えられるのがリストの利点よん。
157 名前:デフォルトの名無しさん mailto:sage [2006/02/08(水) 19:46:04 ] ありがとうございます。 currentとpreviousとtempのほかにもうひとつ必要だったのですか。 そうすると、メインプログラムも変えないとだめってことでしょうか?
158 名前:デフォルトの名無しさん mailto:sage [2006/02/08(水) 19:54:31 ] メイン変えなくてもできますね。とりあえず、できました。次を示すフィールドをpointerとして ppred・・previous pp・・current psucc・・next pwork・・tempになってます。 procedure change; var p,n:integer; previous,temp,next:list; begin n:=1; write('入れ替える位置を指定しなさい'); readln(p); current:=init; while current^.pointer <> nil do begin previous:=current; current:=current^.pointer; next:=current^.pointer; n:=n+1; if n=p then begin temp:=next^.pointer; previous^.pointer:=next; next^.pointer:=current; current^.pointer:=temp end; end; current:=init; while current^.pointer <> nil do begin write(current^.name,' ',current^.id,' '); current:=current^.pointer end; writeln end;
159 名前:774RR mailto:sage [2006/02/08(水) 20:44:27 ] 手続きを仕えってなら、こんなのはどうだ? Program Enjoy2chList; type plist = ^listitem; listitem = record data : string; next : plist end; var top, tail : plist; s : string; toend : boolean; procedure addtolist(s : string); var p : plist; begin new(p); p^.data := s; p^.next := top^.next; top^.next := p end;
160 名前:774RR mailto:sage [2006/02/08(水) 20:45:13 ] procedure exchange(pprev : plist); var pnext, ptemp : plist; begin if pprev<>nil then begin ptemp := pprev^.next; pnext := ptemp^.next; if pnext <> tail then begin ptemp^.next := pnext^.next; pnext^.next := ptemp; pprev^.next := pnext end else writeln('The item is at the tail of the list...') end end; function findprev(key : string) : plist; var p : plist; begin tail^.data := key; p := top; while p^.next^.data <> key do p := p^.next; if p^.next <> tail then findprev := p else begin writeln(key, ' is not found ... Orz'); findprev := nil end end;
161 名前:774RR mailto:sage [2006/02/08(水) 20:45:49 ] procedure disp; var p : plist; i : integer; begin p := top^.next; i := 0; while p<>tail do begin i := succ(i); writeln(i, ' ', p^.data); p := p^.next end end; procedure initlist; begin new(top); new(tail); top^.next := tail; tail^.next := nil end;
162 名前:774RR mailto:sage [2006/02/08(水) 20:46:44 ] procedure disposelist; var p : plist; begin p := top; while top<>nil do begin p := top^.next; dispose(top); top := p end end;
163 名前:774RR mailto:sage [2006/02/08(水) 20:47:23 ] begin initlist; toend := false; repeat write('ENTER Any word to add or NULL to quit: '); readln(s); if s='' then toend := true else begin addtolist(s); disp end until toend; toend := false; repeat write('ENTER Any word to exchange or NULL to quit: '); readln(s); if s='' then toend := true else begin exchange(findprev(s)); disp end until toend; disposelist end.
164 名前:デフォルトの名無しさん mailto:sage [2006/02/08(水) 20:53:39 ] 読まずにすまそ。壱から書く方がらくなんで… 粘着もすまそでつ。 最近もの書きばっかやっているんで たまにプログラムを書かないと脳が腐る ●rz
165 名前:774RR mailto:sage [2006/02/08(水) 20:54:35 ] ↑いけねえハン忘れた orz ともかく帰依まつ
166 名前:デフォルトの名無しさん mailto:sage [2006/02/08(水) 20:57:01 ] ありがとうございます。 この問題はもう解けました。 次の問題は、カーソルによるリスト構造の実現で、INSERT、DELETE,配列SPACEの全 セルを使用可能スペースリストにつなぐinitializeの手続きにエラーチェックを加え、メインプログラム にて確認しなさい。という問題なのですが、これからそれぞれの手続きを書きますのでよろしく お願いします。 参考:ttp://www.elect.chuo-u.ac.jp/automount/tsuki/Tsuki-lab/tsuki/Chap-2/2.4.pdf これはC?で書いてあります。
167 名前:デフォルトの名無しさん mailto:sage [2006/02/08(水) 21:01:46 ] まず、基本的な型宣言から var SPACE:array[1..maxlegth] of record element:elementtype; next:integer end elementtypeって何?って感じです・・・。 次にセルを移動するmove関数 function move(var p,q:integer):boolean; var temp:integer; begin if p=0 then begin writeln('セルがない'); return(false) {retuenってなに?} end else begin temp:=q; q:=p; p:=SPACE[q].next:=temp; retuen(true) end end;
168 名前:デフォルトの名無しさん mailto:sage [2006/02/08(水) 21:11:53 ] 手続きINSERT procedure INSERT(x:elementtype;p:position;var L:LIST); begin if p=0 then begin{最初の位置に挿入} if move(available,L) then SPACE[L].element:=x end else{最初以外の位置に挿入} if move(available,SPACE[p].next)then {xのセルをSPACE[p].nextがさしている} SPACE[SPACE[p].next].element:=x end;{INSERT} 次に手続きDELETE procedure DELETE(p:position;var L:LIST); begin if p=0 then move(L,available) else move(SPACE[p].next,available) end;{DELETE} 最後に手続きinitialize procedure initialize; var i:integer; begin for i:=mazsize-1 downto 1 do SPACE[i].next:=i+1; available:=1; SPACE[maxsize].next:=0 end;{inisialize}
169 名前:デフォルトの名無しさん mailto:sage [2006/02/09(木) 16:05:59 ] 誰か識者の方、166-168の問題解いてもらえませんか? よろしくお願いします。
170 名前:デフォルトの名無しさん mailto:sage [2006/02/10(金) 12:46:42 ] 与えられた自然数 n(n>=3) に対し、正n角形とその対角線を表示するプログラムを作れ。 ただし、Readlnでnの値を読み込んでから作図するようにせよ。 TopPascalのこのような課題が出ました。 どうか皆様の力をお貸しください。
171 名前:デフォルトの名無しさん [2006/02/16(木) 09:43:19 ] 170に答えてください。お願いします。
172 名前:デフォルトの名無しさん [2006/02/16(木) 10:08:26 ] >>171 お前は1週間何やってたんだと小一時間説教してやる。
173 名前:デフォルトの名無しさん mailto:sage [2006/02/16(木) 11:18:23 ] そろそろ説教も終わった頃かね TopPascalもコマンドラインで描画の方法も知らんけど、 Delphi で n 角形の各頂点の位置なら procedure GetApex(ApexCount: Integer;// 頂点の数 Radius: Integer; // 外接円の半径 Center: TPoint; // 外接円の中心 var Apexes: array of TPoint); // 結果 var i: Integer; CurAngle: Double; begin // 初期値 CurAngle := 0; for i := 0 to ApexCount - 1 do begin Apexes[i].X := Center.X + Trunc(Radius * Cos(CurAngle)); Apexes[i].Y := Center.Y + Trunc(Radius * Sin(CurAngle)); CurAngle := CurAngle + 2 * PI / ApexCount; end; end; てけとーに真似してやってみれ
174 名前:デフォルトの名無しさん [2006/02/16(木) 20:41:13 ] ありがたいのですが、Delpiってのはわからないんで…。 できればどなたかコピペしてランすればできるのを提供していただけないでしょうか?
175 名前:デフォルトの名無しさん [2006/02/16(木) 21:26:19 ] プギャ━━━m9。゚゚(゚^Д^≡^Д^゚)゚゚。9m━━━━!!!!
176 名前:デフォルトの名無しさん mailto:sage [2006/02/17(金) 00:14:19 ] デルピ
177 名前:デフォルトの名無しさん mailto:sage [2006/02/17(金) 02:40:34 ] もうデルピーは居ないんだよ・・・
178 名前:デフォルトの名無しさん mailto:sage [2006/02/17(金) 05:12:41 ] 次はデルピーって言うのか出るのが楽しみだ(ノ´∀`*)
179 名前:デフォルトの名無しさん [2006/02/20(月) 01:59:19 ] 「■全く分かってない阿呆も放置しないで優しく対応」という ことに甘えまして、宜しくお願いいたします。 文字列型(あくまで)で、00〜ffに対し、 最終integer型で0〜255に変換したいのですが・・。 たとえば、 var a:string; b:integer; begin a:='2f'; ・ ・ ・ ・ write(b); end. ここでのCRT出力を 「47」 としたい訳です。 どのような手法で可能でしょうか?ご教示下さい。
180 名前:デフォルトの名無しさん mailto:sage [2006/02/20(月) 08:45:30 ] 0-fの文字を0-15の整数に変換する関数hogeを書く。 hogeを使って一文字づつ変換して16倍するループを書く。
181 名前:デフォルトの名無しさん [2006/02/20(月) 19:40:25 ] >>180 有り難うございます、一寸やってみます。
182 名前:デフォルトの名無しさん mailto:sage [2006/02/22(水) 01:09:37 ] こんなのどうですか。 function HexToInt(const S: string): Integer; const Table: array['0'..'F'] of Integer = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15); var I: Integer; begin Result := 0; for I := 1 to Length(S) do Result := Result shl 4 + Table[UpCase(S[I])]; end;
183 名前:デフォルトの名無しさん mailto:sage [2006/02/22(水) 04:56:14 ] 解析してアセンブラまで戻すにはするにはどうしたらいいですか?
184 名前:デフォルトの名無しさん mailto:sage [2006/02/22(水) 10:52:30 ] ファイト
185 名前:デフォルトの名無しさん mailto:sage [2006/02/24(金) 19:58:02 ] 一発
186 名前:デフォルトの名無しさん [2006/03/24(金) 06:02:22 ] ―u
187 名前:デフォルトの名無しさん [2006/04/11(火) 17:32:22 ] 時、分、秒で表した時間の和を計算するプログラムを作成したい。 但し、以下の条件を満たすように作成し、 プログラムと適当なデータを入力した結果と一緒に提出せよ。 1. データは日、時間、分、秒を表す整数型のフィールド名 day, hour, minute, second のレコード型で定義し、 レコード名を time とせよ。プログラム名を Toi2 とし、 秒と分の計算課程は同一であるため、 その個所は手続きを使って表現せよ。 2. 入力として、時、分、秒の 3個のデータを 2セット入力し、その和を出力せよ。 3. もし、 hour の値が 24 以上であれば day に1の値を、 24未満であれば零にせよ。
188 名前:デフォルトの名無しさん [2006/04/11(火) 17:34:13 ] フィボナッチ数列の項は、その直前の連続する二つの項の和である。 f( n ) = f( n - 1 ) + f( n - 2 ) 但し、 f(0) = 0, f(1) = 1 である。 フィボナッチ数列の連続する項の差の比 z(n) = { f( n - 1 ) - f( n - 2 ) }/ { f( n ) - f( n - 1 ) } は、 n が大きくなれば、ある値に収束する。この値の近似値を求める プログラムを書き、その値を示せ。この値は黄金分割比と呼ばれる。 プログラム名を Toi3 とし、フィボナッチ数列は関数 fibonacci を作って求め、項は配列に表せ。数列は 100項まで とする。 1. まず f(30)の項まで求めz(n)の値を出力させるプログラムを作り、その値が 収束していく様子を出力して確かめよ。 2. 次に、1.のプログラムを書き換えて、収束判定のために定数 dif = 1.0 e -6 を宣言し、 連続する z(n-1),z(n) の差の 絶対値が dif 以下になったとき、収束したとして計算を終了する プログラムを作り、 プログラムとその計算結果を提出せよ。 もし、n=100でも 収束しない場合、z(100)の値と”収束しなかった”文を出力せよ。
189 名前:774RR mailto:sage [2006/04/11(火) 18:52:31 ] Program Toi2; type time = record day, hour, minute, second : integer end; var t1, t2, t3 : time; procedure add60(a, b : integer; var c : integer; var carry : boolean); (* a + b must be less than 120 *) begin c := a + b; carry := (c >= 60); c := c mod 60 end; begin (* データを読む1 -> t1 *)(* データを読む2 -> t2 *) add60(t1.second, t2.second, t3.second, cry); add60(t1.minute, t2.minute + ord(cry), t3.minute, cry); with t3 do begin hour := t1.hour + t2.hour + ord(cry); if hour >= 24 then begin day := 1; hour := hour -24 end else day := 0 end; (* 表示 *) end.
190 名前:デフォルトの名無しさん mailto:sage [2006/04/11(火) 19:43:31 ] >>189 carryとcryをintegerにしてcarry:=(c>=60);をcarry:=c div 60;にすれば (* a + b must be less than 120 *)の注意書きも要らなくなると思う。 そうすれば+ord(cry)をそのまま+cryに出来るし。
191 名前:デフォルトの名無しさん [2006/04/12(水) 12:14:53 ] >>189 cryって何ですか? ほかにもコンパイルエラー出てるんですけど?
192 名前:190 mailto:sage [2006/04/12(水) 13:40:29 ] >>191 少しは自分で考えて。宣言がいくつか足りないのと、初期化やデータの 入出力をどうするのかは>>187 に出ていないのでその部分は自分で書く 必要がある。
193 名前:188 [2006/04/12(水) 15:19:52 ] program Toi3(input,output); var i,n: integer; f,z: array [0..1000] of integer; function fibonacci(n : integer):integer; begin case n of 3..1000 : fibonacci:=fibonacci(n-1)+fibonacci(n-2); 1,2 : fibonacci:=1; 0 : fibonacci:=0 end; { case } end; begin write('n='); readln(n); for i:=0 to n do begin f[i]:=fibonacci(i); z[i]:=(f[n-1]-f[n-2])div(f[n]-f[n-1]); writeln('f(',i:2,')=',f[i]:1,', '); writeln(); writeln('z(',i:2,')=',z[i]:1,', '); end; end. というのを作ったのですが、コンパイルはできるのに値を入力しても答えが出力されませんorz
194 名前:188 [2006/04/12(水) 15:20:31 ] program Toi3(input,output); var i,n: integer; f,z: array [0..1000] of integer; function fibonacci(n : integer):integer; begin case n of 3..1000 : fibonacci:=fibonacci(n-1)+fibonacci(n-2); 1,2 : fibonacci:=1; 0 : fibonacci:=0 end; { case } end; begin write('n='); readln(n); for i:=0 to n do begin f[i]:=fibonacci(i); z[i]:=(f[n-1]-f[n-2])div(f[n]-f[n-1]); writeln('f(',i:2,')=',f[i]:1,', '); writeln(); writeln('z(',i:2,')=',z[i]:1,', '); end; end. というのを作ったのですが、コンパイルはできるのに値を入力しても答えが出力されませんorz
195 名前:188 [2006/04/12(水) 15:29:40 ] z[i]:=(f[n-1]-f[n-2])div(f[n]-f[n-1]); は, z[i]:=(f[i-1]-f[i-2])div(f[i]-f[i-1]); の間違いです。 しかしまだ何かがおかしいらしい。
196 名前:デフォルトの名無しさん [2006/04/12(水) 15:41:52 ] パスカルでおしえて大学生を抹殺するプログラムを作ろうと思いますが、 コメントの記念すべき一文字目は何にしようか迷ってます。
197 名前:774RR mailto:sage [2006/04/12(水) 17:10:04 ] >190 そりゃそーなんだけど、キャリーはやっぱりフラグでしょw >195 fibonacci関数は動くはずだから、それだけテストしてみるといい。 fibonacci(1) fibonacci(2) fibonacci(3) と増やしていって、 fibonacci(100)の計算にどれだけ時間かがかかるか、ためしてごらん。 どうしてこんなに遅いのか、どうしたら効率良くできるのか。 そうすると for i:=0 to n do f[i]:=fibonacci(i); てのが 原理的には正しくても酷く悪いコーディングだと気付く。 それが勉強だよ。
198 名前:デフォルトの名無しさん mailto:sage [2006/04/12(水) 17:17:40 ] 俺は詳しくないからどうすればいいプログラムになるかというレベルではアドバイスできないんだけど for文の中で"i"が"0"のときに z[i]:=(f[i-1]-f[i-2])div(f[i]-f[i-1]); というのは z[0]:=(f[-1]-f[-2])div(f[0]-f[-1]); ってことになってないかい? あと整数型における"div"ってのは商を求める演算子であって 実数型における"/"とは違うってことは分かってる?
199 名前:188 [2006/04/13(木) 14:58:02 ] すっごい効率が悪いこととか、i=0のこととか、わかってるのですがどうすればいいのかがわからないすorz
200 名前:デフォルトの名無しさん mailto:sage [2006/04/13(木) 15:50:10 ] 3..1000 : fibonacci:=f[n-1]+f[n-2];
201 名前:デフォルトの名無しさん [2006/04/13(木) 19:22:52 ] case文で、例えば「nの値が0の時は■、1の時は▲、2以上の時は●」としたいとき、 「2以上の時は●」のところはどうやって表記すればいいのですか? case n of 0 : ■; 1 : ▲; >=2 : ●; とするとコンパイルエラーになってしまうのです(泣)
202 名前:デフォルトの名無しさん mailto:sage [2006/04/13(木) 21:55:02 ] >>201 caseは順序型だから、下限、上限が決まっている。で、2からその上限まで を指定すればいいってことになる。具体的には case n of 0 : ■; 1 : ▲; 2..100 : ●; とすればいい(上限値が100の場合)。
203 名前:デフォルトの名無しさん mailto:sage [2006/04/13(木) 23:26:19 ] case n of 0 : ■; 1 : ▲; else if n >= 2 then ●; end;
204 名前:202 mailto:sage [2006/04/13(木) 23:35:57 ] >>203 それ通らない処理系もある(というか標準Pascalだとcase節にelseは無い)。
205 名前:デフォルトの名無しさん [2006/04/13(木) 23:42:30 ] caseのどの条件にも該当しなかったことを検出するにはどうすればいいのですか?
206 名前:デフォルトの名無しさん mailto:sage [2006/04/13(木) 23:53:14 ] >>205 論理型変数を一つ用意して最初にfalseにしておく。 そのあとでcase文中の任意の条件にマッチした場合はtrueに変更してやる。 そうすれば該当しなかった場合はfalseのままだからfalseの場合なにかするっていうように すれば一応できるんじゃない?
207 名前:202 mailto:sage [2006/04/13(木) 23:58:22 ] >>205 だからcase節の変数部(上記nの所)は順序型しか指定できないわけ だから、上限、下限が決まっていて、個数も自ずと出てくるわけ。 だから「どの部分にも該当しなかった」という部分を抜き出すことも可能 でしょ。それをどこかで指定してやればいいわけ。例えば以下のような 感じで。 case n of 5 : ■; 8 : ▲; 15 : ●; 0..4, 6, 7, 9..14, 16..100 : ×; (* どの条件にも該当しない場合 *) これは、nが0から100までの値を取る順序型の場合。範囲がそれ以外 の場合は適宜指定してやればいい。
208 名前:デフォルトの名無しさん mailto:sage [2006/04/14(金) 06:54:53 ] pascal ha erai mendou na gengo desune.
209 名前:201 [2006/04/14(金) 16:04:04 ] >>202 上限がないから困っているわけでw if文で書くしかないですかね?
210 名前:デフォルトの名無しさん mailto:sage [2006/04/14(金) 17:00:59 ] if n >= 2 then begin ●; end else begin case n of 0 : ■; 1 : ▲; end; じゃダメなのか?