パスカル言語の要素交換や要素ソートについて

このQ&Aのポイント
  • パスカル言語の必修科目であるパスカル言語の要素交換や要素ソートについて解説します。
  • 要素の交換方法を示すコードを示し、要素を交換する方法を理解しました。要素のソート方法についても解説しています。
  • 要素のソート方法の中で要素の入れ替えが行われる箇所について、理解できない部分があります。質問内容に詳細を記載しており、回答をお願いします。
回答を見る
  • ベストアンサー

パスカル言語

通信大学の必修科目でパスカル言語を勉強し始めたのですが、 Tausch := ioZeigerEins; ioZeigerEins := ioZeigerZwei; ioZeigerZwei := Tausch; のように、ioZeigerEins と ioZeigerZwei を交換するやり方は理解できたのですが、 procedure SortiereListe の中の、 Tausch := Element^.next; Element^.next := Anfang; Ende^.next := Tausch; ZeigerTausch (Anfang, Element); で、どうしてElement^.next が出てくるのかが良く理解出来ません。 長々と書いてしまいましたが、どうぞ宜しくお願い致します。 ------------------------------------------------------ program TesteSortiereListe (input, output); type tNatZahl = 0..maxint; tRefListe = ^tListe; tListe = record info : tNatZahl; next : tRefListe; end; var RefListe : tRefListe; procedure SortiereListe (var ioRefListe : tRefListe); { sortiert eine lineare Liste aufsteigend } var Anfang, Ende, Tausch, Suche, Element : tRefListe; function ZeigerTausch (var ioZeigerEins, ioZeigerZwei : tRefliste) : tRefListe; begin Tausch := ioZeigerEins; ioZeigerEins := ioZeigerZwei; ioZeigerZwei := Tausch; end; { ZeigerTausch } begin if (ioRefListe <> nil) and (ioRefListe^.next <> nil) then begin Anfang := ioRefListe; Ende := ioRefListe^.next; if Ende^.info < Anfang^.info then begin Anfang^.next := Ende^.next; Ende^.next := Anfang; ZeigerTausch (Ende, Anfang); end; { if-Schleife } while Ende^.next <> nil do begin Element := Ende^.next; if Element^.info > Ende^.info then Ende := Ende^.next else if Element^.info < Anfang^.info then begin Tausch := Element^.next; Element^.next := Anfang; Ende^.next := Tausch; ZeigerTausch (Anfang, Element); end { then-Zweig } else begin Suche := Anfang; while Suche^.next^.info < Element^.info do Suche := Suche^.next; Tausch := Element^.next; Element^.next := Suche^.next; Suche^.next := Element; Ende^.next := Tausch; end; { else-Zweig } end; { while-Schleife } end; { if-Schleife } ioRefListe := Anfang; end; {SortiereListe } procedure Anhaengen (var ioListe : tRefListe; inZahl : tNatZahl); { Haengt inZahl an ioListe an } var Zeiger : tRefListe; begin Zeiger := ioListe; if Zeiger = nil then begin new(ioListe); ioListe^.info := inZahl; ioListe^.next := nil; end else begin while Zeiger^.next <> nil do Zeiger := Zeiger^.next; new(Zeiger^.next); Zeiger := Zeiger^.next; Zeiger^.info := inZahl; Zeiger^.next := nil; end; end; procedure ListeEinlesen(var outListe : tRefListe); { liest eine durch Leerzeile abgeschlossene Folge von Integer- Zahlen ein und speichert diese in der linearen Liste RefListe. } var Liste : tRefListe; Zeile : string; Zahl, Code : integer; begin writeln('Bitte geben Sie die zu sortierenden Zahlen ein.'); writeln('Beenden Sie Ihre Eingabe mit einer Leerzeile.'); Liste := nil; readln(Zeile); val(Zeile, Zahl, Code); { var konvertiert String nach Integer } while Code=0 do begin Anhaengen (Liste, Zahl); readln (Zeile); val (Zeile, Zahl, Code); end; { while} outListe := Liste; end; {ListeEinlesen} procedure GibListeAus(inListe : tRefListe); { Gibt die Elemente von inListe aus } var Zeiger : tRefListe; begin Zeiger := inListe; while Zeiger <> nil do begin writeln(Zeiger^.info); Zeiger := Zeiger^.next; end; { while } end; { GibListeAus } begin ListeEinlesen(RefListe); SortiereListe(RefListe); GibListeAus(RefListe); end.

質問者が選んだベストアンサー

  • ベストアンサー
  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.2

いわゆる「連結リスト」というデータ構造なので、ここらあたり参考にしてみては。 http://ja.wikipedia.org/wiki/%E9%80%A3%E7%B5%90%E3%83%AA%E3%82%B9%E3%83%88

Aepfelchen
質問者

お礼

理解できました✿ 参考リンクどうもありがとうございました! また分からなくなった時には宜しくお願い致します。

その他の回答 (1)

  • notnot
  • ベストアンサー率47% (4846/10257)
回答No.1

>どうしてElement^.next が出てくるのかが良く理解出来ません。 と言われても、「そこに必要な情報が入っているから」としか言えません。

関連するQ&A

  • 2分木を中順でなぞりたいのですが(pascal)

    課題で「2分探索木にデータを挿入する手続きを定義し、作った木を中順になぞって出力せよ」というのが出されました。       6      /  \     4    7     /     \    2      9     \   /  \     3   8   10            \            11               \              12 このような木を考えプログラムを組み実行できたのですが、結果が「2,3,4,6,7,8,9,10,11,12」となってしまいます。中順だと「3,2,4,6,8,9,12,11,10,7」のはずなので合いません。 どこがおかしいのかご指摘お願いします。 ソースは以下の通りです。 program tree_search (input,output); type elementtype = integer; pointertype = ^celltype; celltype = record element : elementtype; leftson : pointertype; rightson: pointertype end; var root : pointertype; procedure inorder( node:pointertype); begin if (node <> nil) then begin inorder( node^.leftson); write( node^.element); inorder( node^.rightson) end end; {中順になぞる} procedure insert( x:integer; var p:pointertype); begin if ( p = nil) then begin new( p ); p^.element := x; p^.leftson := nil; p^.rightson := nil end else if ( x < p^.element ) then insert( x,p^.leftson) else if ( x > p^.element ) then insert( x,p^.rightson) end; {木に挿入する} procedure create( var p:pointertype ); begin p:= nil end; {空の木を作る} begin create(root); insert( 6,root ); insert( 4,root ); insert( 2,root ); insert( 3,root ); insert( 7,root ); insert( 9,root ); insert( 8,root ); insert( 10,root ); insert( 11,root ); insert( 12,root ); inorder( root ) end.

  • pascal二分木の課題

    レポート課題で、pascalの二分木についての問題が出たのですが、うまくソースコードを作ることができません! 誰かお手伝いよろしくお願いします! 課題:progに木をバランスよく組みなおす関数repackを追加せよ program prog(input,output); const maxRange = 100; type dataType = integer; tree = ^treeCall; treeCall = record data:dataType; left,right:tree end; var root:tree; command:char; value:dataType; function search(d:dataType; t:tree):tree; begin if t=nil then search:=nil(*ブレーク*) else if t^.data=d then search:=t(*見つけた*) else if t^.data>d then search:=search(d,t^.left)(*左を検索*) else search:=search(d,t^.right)(*右を検索*) end; procedure insert(d:dataType; var t:tree); begin (**) if t=nil then begin new(t); t^.data:=d; t^.left:=nil; t^.right:=nil end else if t^.data=d then (*すでに登録されているので何もしない*) else if t^.data>d then insert(d,t^.left) else insert(d,t^.right); end; procedure delete(d:dataType; var t:tree); var temp:tree; procedure deleteMin(var r:tree); var temp:tree; begin temp:=r; while temp^.left<>nil do temp:=temp^.left; t^.data:=temp^.data; delete(temp^.data,r) end; begin if t=nil then writeln('Not Exist.') else if t^.data=d then if (t^.left<>nil) and (t^.right<>nil) then deleteMin(t^.right) else begin temp:=t; if t^.left<>nil then t:=t^.left else t:=t^.right; dispose(temp); end else if t^.data>d then delete(d,t^.left) else delete(d,t^.right) end; procedure writeSet(t:tree); begin if t=nil then (*何もしない*) else begin writeSet(t^.left);(*左へ左へ・・・*) write(t^.data:1,' '); writeSet(t^.right)(*右へ・・・*) end end; (****** Body ******) begin root:=nil; repeat write('> '); read(command); if command in ['i','d','s','w'] then begin (*もしもコマンドがw以外なら値を読み込む*) if command='w' then readln else readln(value); case command of (*数値をバイナリーツリーに挿入 ここでソーティングしたい*) 'i': insert(value,root); 'd': delete(value,root);

  • 線形リスト上で方程式の計算をしたい(pascal)

    線形リスト上で2個の一次方程式を入力しその和を出力するプログラムを作っています。 x + y . 2 y . x+3y   このように一文字ずつ入力(改行で区切る)、係数が1の場合は変数のみを入力、ピリオドが入力されたら次の式を入力、またピリオドが入力されたら結果を表示するものです。 考えてみたのですが、「1文字目に2から9までの数字が代入された場合とそうでない場合」「2文字目に+-の符号が代入された場合・・・」「3文字目に・・・」と分岐が多くなりアルゴリズムを考える段階で手詰まりしてしまいました。 どう考えて解けばいいのかお教えください。 この課題の前の課題を参考にしろとのことで、定義には↓のようなものがあります。 type list = ^mojirec; mojirec = record moji : char; kaisu : integer; next : list end; var   found : boolean; p := head; while not found and (p<>nil) do if p^.moji = v then found := true else p := p^.next; procedure print( p : list ); begin if p<> nil then begin writeln( p^.moji,p^.kaisu ); print( p^.next ) end end;

  • 整順リスト形式の英単語辞書(pascal)

    キーボードから「英文」を読み込み、空白(スペース)を英単語の区切りとみなして英単語辞書を整順リスト形式で作りたいのですがうまくいきません。 ソースとコンパイル結果の間違いは↓にありますが、そもそも v := read( sentences ) なんてのが可能なのかもわかりません。(readは最初から一文字ずつ読むとか聞いたのでこうしたのですが・・・) どなたかご教授ください。 program kadai(input,output); type list = ^mojirec; mojirec = record newword : packed array[1..20] of char; next : list end; var sentences,v : packed array[1..500] of char; p,head : list; procedure insert(var p : list; x : packed array[1..20] of char ); var q : list; begin if p = nil then begin new(p); p^.newword := x; p^.next := nil end else if x < p^.newword then begin q := p; new( p ); p^.newword := x; p^.next := q end else insert( p^.next,x ) end; procedure print( p : list ); begin if p<> nil then begin writeln( p^.newword ); print( p^.next ) end end; begin head := nil; write('英文:'); readln( sentences ); repeat repeat repeat read( sentences ); v := read( sentences ); until( read('') ); insert( head,v ) until ( read('.') ); writeln('英文:'); until ( sentences = '.' ); print( head ) end. In program kadai: E 18240 x undefined on lines 16 19 22 26 E 18240 insert undefined on line 26 終了条件はピリオド単体を読み込んだとき、英文の最後はピリオドを付けるようにとなっています。

  • Pascal言語で小町算

    Pascal言語で、『1~9の順に数字を並べ、+、-を補い式を作り、 値が100になる組み合わせをすべて出力するプログラムを作成せよ(例:12 - 3 - 4 + 5 - 6 + 7 + 89 = 100)。』 という課題が出ました。自分なりに組んでみたのですが、 12個あると聞いたのに、4個しか出力されません><; どこが間違っているのかご教授いただけると幸いですっ ------------------------------------------------------- program KomachiZan(output); var i,s:integer; var sign:array[1..9] of integer; var x,n:longint; begin writeln('< 小町算 -Komachi Zan- >'); for i:=1 to 9 do sign[i]:=-1; repeat x:=0; n:=0; s:=1; for i:=1 to 9 do begin if sign[i]=0 then n:=10*n+1 else begin x:=x+s*n; s:=sign[i]; n:=i; end; end; x:=x+s*n; if x=100 then begin for i:=1 to 9 do begin if sign[i]=1 then write(' + ') else if sign[i]=-1 then write(' - '); write(i); end; writeln(' = 100'); end; i:=9; s:=sign[i]+1; while s>1 do begin sign[i]:=-1; i:=i-1; s:=sign[i]+1; end; sign[i]:=s; until sign[1]>=1; end. -------------------------------------------------------

  • 除算がなぜかできません(pascal)

    フィボナッチ数列の連続する項の差の比  z(n) = { f(n-1) - f(n-2) } / { f(n) - f(n-1) } 、 これのz(n-1),z(n)の差の絶対値がある定数以下になった時(100項まで)に計算を終了するプログラムを作ったのですが、何度コンパイルしても上の式の除算部でエラーが起きてしまいます。 どこがおかしいのかご教授ください。 program Toi3 (input,output); const dif = 1.0 * exp(-6); var n : integer; result : real; function f(n:integer):integer; begin if(n>=0)and(n<=1) then f:=1 else f:=f(n-1)+f(n-2); end;{f} function z(n:integer):real; begin z := {f(n-1) - f(n-2)}/{f(n)-f(n-1)} end; begin n:=2; while (n=100) or (result<dif) do begin n:=n+1; result:= abs(z(n)-z(n-1)) end; if n=100 then begin result:= abs(z(100)-z(99)); if result<dif then begin writeln('収束した') end else begin writeln( z(100),'収束しなかった') end end else begin writeln('収束した') end end. エラー: 17 z := {f(n-1) - f(n-2)}/{f(n)-f(n-1)} E 18460--------------------------------^--- Replaced '/' with a identifier In function z: w 18270 variable n is never used

  • Pascalでの選択ソート

    program sort(input, output); const numofdata =100 ; var d: array [1..numofdata] of integer; i,j,k: integer; tmp: integer; begin for i:=1 to numofdata do begin read(d[i]); end; for i:=1 to numofdata-1 do begin j:=i; for k:=i+1 to numofdata do begin if d[j]>d[k] then j:=k; end; tmp:=d[j]; d[j]:=d[i]; d[i]:=tmp; end; for i:=1 to numofdata do begin writeln(d[i]) end end. このプログラムを、データ数(1個から最大10000個まで)を最初に入力できるように変更するには、どうすればよいのでしょうか。教えてください。

  • Pascal  insertの使い方

    プログラミングの授業で 整数(integer)を入力して、金額表示のように3桁ごとにコンマを打って文字列(string)として表示せよ。 という問題が出されました。 やってみた結果が下なんですが、insertがまちがってぃて実行されません。どこが間違ってるか教えてもらえませんか。 program prj7_2(input,output); var st,u,con:string[100]; n,i,x:integer; begin writeln('数を入力してください。'); readln(st); n:=length(st); if n<=3 then writeln(st) else begin i:=1; con:=','; repeat x:=n-3*i; u:=insert(con,st,x); until x:<3; writeln(u); end; end.

  • クイックソート後の出力(pascal)

    20個の整数データをクイックソートして出力せよ、という課題が出ました。クイックソートまでは出来た(コンパイルできたのでおそらく)のですが、その順に出力する方法がわかりません。どなたかお教えください。 program sort(input,output); const n = 20; type index = 1..n; var A : array[1..n] of integer; i,x,a : integer; p,j,k : index; function PIVOT(i,j : index):integer; var k:index; begin k:=i+1; while (A[i]=A[k]) and (k<=j) do k:=k+1; if k>j then PIVOT:=0 else if A[i]>=A[k] then PIVOT:=i else PIVOT:=k end; procedure SWAP(var x,y:integer); var temp:integer; begin temp:=x; x:=y; y:=temp end; procedure PARTITION(i,j:index; a:integer; var k:index); var l,r:index; begin l:=i; r:=j; while A[l]<a do l:=l+1; while A[r]>=a do r:=r-1; while l<=r do begin SWAP(A[l],A[r]); l:=l+1; r:=r-1; while A[l]<a do l:=l+1; while A[r]>=a do r:=r-1; end; k:=l end; procedure QUICKSORT(i,j:index); var a:integer; p:index; k:index; begin p:=PIVOT(i,j); if p<>0 then begin a:=A[p]; PARTITION(i,j,a,k); QUICKSORT(i,k-1); QUICKSORT(k,j) end end; begin i:=0; i:=1+1; for i:= 1 to n do begin A[i]:=0; end; i:=0; i:=i+1; for i:= 1 to n do begin readln(x); A[i]:=x end; a:=PIVOT(p,j); PARTITION(p,j,A[a],k); QUICKSORT(p,j) end. QUICKSORT(p,j)とend. の間に出力方法を書き込みたいのです。

  • 2つの年月日の間の日数を求めるプログラム(PASCAL)

     大学の講義で、「2つの年月日を入力し、その年月日の間の日数を求めるプログラムを作成しなさい」という宿題が出たので、下のようにプログラムを作成したところ、…63(最後の行):parse error before '.'というエラーが出たのですが、なぜそのようなエラーが出るのかがわかりません。どう改善すべきか、アドバイスをお願いします。 program ex13(input,output); var year1,year2:1..9999; month1,month2:1..12; y1,y2:1..9999; m1,m2:1..12; d1,d2:1..31; n1,n2:1..9999999; begin writeln('question 13'); writeln('Please key the old date.'); write('Y: '); read(y1); write(' M: '); read(m1); write(' D: '); readln(d1); writeln('Please key the new date.'); write('Y: '); read(y2); write(' M: '); read(m2); write(' D: '); readln(d2); for year1:= 1 to y1 do begin if ((year1 mod 4 = 0) and not (year1 mod 100 = 0)) or (year1 mod 400 = 0) then n1:=n1+366 else n1:=n1+365 end; for month1:= 1 to m1 do begin case month1 of 3,5,7,8,10,12,1: n1:=n1+31; 4,6,9,11: n1:=n1+30; 2: if ((y1 mod 4 = 0) and not (y1 mod 100 = 0)) or (y1 mod 400 = 0) then n1:=n1+29 else n1:=n1+28 end; n1:=n1+d1; for year2:= 1 to y2 do begin if ((year2 mod 4 = 0) and not (year2 mod 100 = 0)) or (year2 mod 400 = 0) then n2:=n2+366 else n2:=n2+365 end; for month2:= 1 to m2 do begin case month2 of 3,5,7,8,10,12,1: n2:=n2+31; 4,6,9,11: n2:=n2+30; 2: if ((y2 mod 4 = 0) and not (y2 mod 100 = 0)) or (y2 mod 400 = 0) then n2:=n2+29 else n2:=n2+28 end; n2:=n2+d2; writeln('Ans.',n2-n1); end.

専門家に質問してみよう