線形リスト上で方程式の計算をするプログラムの作り方

このQ&Aのポイント
  • 線形リスト上で2個の一次方程式を入力しその和を出力するプログラムの作り方を教えてください。
  • 文字ごとに条件分岐を行うことで、入力された方程式の係数や変数を判別し、結果を表示するアルゴリズムを考えることが困難になっています。
  • 前の課題を参考にすることで、線形リスト上で方程式の計算をするプログラムを作ることができます。
回答を見る
  • ベストアンサー

線形リスト上で方程式の計算をしたい(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;

  • rurur
  • お礼率50% (24/48)

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

  • ベストアンサー
  • SHIMAPEE
  • ベストアンサー率75% (154/203)
回答No.1

出題者の意図は、多項式の項を要素とする線形リストを作り、検索、更新させることにあるのではないでしょうか。その前提で考えてみましたのでヒントになりましたら。 まず、例えばrecordを下記のようにするのでは。 type list = ^kourec; kourec = record keisu : integer; (*係数。負の場合もある*) hensu : char; (*変数*) next : list end; x+y.が入力されたら二つのrecordのリストを作ることを考えます。 [+1x]→[+1y] 上記を更に分解すれば、x の入力に対し一つ目のrecordを作って追加、+y の入力に対し二つ目のrecordを作って追加、ピリオドで作成を終了します。 次に 2y の入力に対しリストを検索し、見つかったrecordの係数を変更します。 [+1x]→[+3y] 次にピリオドで表示します。表示のポイントは下記でしょう。 ・係数が全てゼロだったら 空です などど表示して終わる。 ・係数がゼロだったらそのrecordは表示しない。 ・係数が負であれば-符号を表示する。 ・初めての表示でなければ符号を表示する。 ・係数が1なら省略する。 テストです。下記は空になります。 -z+2y-3x.3x-2y+z. [-1z]→[+2y]→[-3x] に [+3x]、[-2y]、[+1z] を加える ----- 順番が逆になりましたが文字読み取りとrecord作成のヒントです。エラーチェックするなら例えばフラグを使って許す文字を判定すればよいのでは。 ・無限ループ  ・recordを係数1に初期化する  ・文字を読むループ   ・ピリオドなら無限ループ終わり   ・符号+なら無視。-なら係数に-1を設定する   ・数字なら係数にかける   ・英字なら変数に設定し、recordをリストに追加する。文字を読むループ終わり ----- 課題の本質ではないと思いますが仕様を詰める必要があるかもしれません。x+xを許すかとか、y+xのときに表示順をx+yにするかとか。エラーチェックをどこまでやるかとか。

rurur
質問者

お礼

ありがとうございます、参考になりました。

関連するQ&A

  • 整順リスト形式の英単語辞書(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 終了条件はピリオド単体を読み込んだとき、英文の最後はピリオドを付けるようにとなっています。

  • パスカル言語

    通信大学の必修科目でパスカル言語を勉強し始めたのですが、 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.

  • 線形リスト

    どうしても解けない課題がありまして、投稿しました。 どうか、お願いします。。。。 課題内容 下記の構造体を利用した線形リストを作り、 文字列の頻度を計算するプログラムを作成することを考えます。 typedef struct node { char *str; int hindo; struct node *next; } Node; このため、以下のヘッダファイルの名前を hindo.h とするとき、 以下の課題に答えなさい。 hindo.h typedef struct node { char *str; int hindo; struct node *next; } Node; Node* newnode(); void dispHindo(Node* p); int countHindo(Node* p, char *key); void delList(Node*p); Node のポインタを与えると、そのポインタが指す線形リストを解釈し、頻度を出力した後 ---------- を出力する void dispHindo(Node* pointer) を作成しなさい。 書式は一行ずつ「文字列: 頻度」となるようにしなさい。 なお、線形リストの最終ノードの next には NULL が入っていることとし、この場合他のメンバの値は使用しないものとします。 そして下記のプログラムと結合し、実行例と同じものが出ることを確認しなさい。 テストプログラム #include <stdio.h> #include "hindo.h" int main(void){ Node x, y , z, end; x.str="abc"; x.hindo=2; x.next=&y; y.str="def"; y.hindo=3; y.next=&z; z.str="ghi"; z.hindo=1; z.next=&end; end.next=NULL; dispHindo(&end); dispHindo(&x); return 0; } 実行例 ---------- abc: 2 def: 3 ghi: 1 ----------

  • 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)

    例えば「長さ:6」と入力すると6桁のフィボナッチ数列の項だけを出力するプログラムを作ってるのですが、意外なところで躓いてしまいました。どこが変なのか教えてください。 program fib_search (input,output); var i,p,x,y : integer; f : array[0..500] of real; function fib(n:integer):integer; begin if(n>=0)and(n<=1) then fib:=1 else fib:=fib(n-1)+fib(n-2); end;{fib} begin writeln('数列の長さ:'); readln(p); x:=0; y:=0; for i:= 1 to 5*p do begin x:= trunc(fib(i)/(10^p)); y:= trunc(fib(i)/(10^(p-1))); if (x=0) and (y>=1) then begin writeln(fib(i)) end end; end. 例えばp=6として、10の6乗で割った数x=0&10の5乗で割った数y>=1 だと6桁、と考えました。1 to 5*p は、ざっと数列を見たところ(桁数×5)項までにその桁の数字はぎりぎり出尽くしている、と考えたからです。 これをコンパイルするとx、y共に「 Replaced '^' with a '+'」と出て、 x:= trunc(fib(i)/10^p); y:= trunc(fib(i)/10^(p-1)) と分母の()を取ると「 Expected ')'」と出てしまいます。 また、「(fib(i))」としても同様「 Replaced '^' with a '+'」と出てしまうのです。

  • 一月前の日付を求めるプログラム(pascal)

    大学の課題で「一月前の日付を求めるプログラムを作れ。その日が無ければその月の最後の日を示す。」というのが出題されました。12月18日(火)と入力すると11月18日(日)、12月31日(月)なら11月30日(金)となる具合です。 列挙型を用い書いてみたのですが、コンパイルしたら「Type-clash」と出てコンパイルできませんでした。どう改善すべきかアドバイスお願いします。 program calender(input,output); type months=(Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Nov,Oct,Dec); weeks=(Mon,Tue,Wed,Thu,Fri,Sat,Sun); var x,x1,z,z1:char; y,y1,p1,p2,i,r:integer; begin writeln('月:'); readln(x); writeln('日:'); readln(y); writeln('曜日:'); readln(z); if x=Jan then begin x1:=Dec end else begin x1:=pred(x)            {x1=表示する月} end; if y>=29 then if x=Mar then begin y1:=28 end else begin y1:=y             {y1=表示する日} end; case x of May,Jul,Aug,Nov,Dec : p1:=30; Jan,Feb,Apr,Jun,Sep,Oct : p1:=31; Mar : p1:=28 {月の違いによる日数の違い} end; p2:=y-y1;     {日にちの違い} r:=(p1+p2)-trunc((p1+p2)/7)*7; {7で割った余り} for i := 1 to r do z1:=pred(z);          {z1=表示する曜日} writeln(x1,'月',y1,'日',z1,'曜日') end.

  • アルゴリズム 線形リスト

    最近リストについて習い始めました。入力したデータと同順に並ぶリストを作成しようと思い、コードを打ったのですが…動作中止の表示がでてしまいました。どこが間違っているのか、ずっと悪戦苦闘して組んでいるのですが、全く出口が見えてきません。何が間違えているのか、はたまた根本的に違うのか、ご指導して頂けると有難いです。 以下、コードです。 #include <stdio.h> #include <stdlib.h> #include <string.h> struct hito{ char name[20]; int age; struct hito *next; }; void main(void){ struct hito *p, *head, *dummy; char new_name[20]; int new_age; dummy = (struct hito *)malloc(sizeof(struct hito)); head = dummy; dummy->next = p; dummy = p; while (scanf("%s %d" , new_name, &new_age) != EOF) { p = (struct hito *)malloc(sizeof(struct hito)); strcpy(p->name, new_name); p->age = new_age; p->next = head; head = p; } while(p != NULL) { printf("\t%-20s %3d\n" , p->name, p->age); p = p->next; } }

  • 線形リスト

    ファイルから単語を読み込んでいき、単語とその単語の数を出力するプログラムです。単語の区切り方は英文字以外の時です。 例 http://www.sig.sig.org だったとしたら http 1回 www 1回 sig 2回 org 1回 という課題なのですが、while文で読み込んで英文字以外が入力されるたびにif文でぬけ、単語の登録、比較するプログラムを作ったのですが、まったく動きません。(たぶん関数への引渡しとかがおかしいのだと思うのですが) どこがどうちがうのか教えてくださいお願いします。 #include<stdio.h> struct node{//構造体 int count; char tango[20]; struct node *next; }; struct node *new(char t[20]) {//単語の入力 struct node *p; strcpy(p->tango,t); p->count=0; return p; } struct node *in(struct node *p,char t[20]) {//単語の比較 int c; c=strcmp(p->tango,t); if(c==0){ p->count++; return p; } else if(p->next==NULL) {p->next=new(t);} else {in(p->next,t);} } int *pt(struct node *p){//出力 if(p==NULL)return; else printf("%s:%d\n",p->tango,p->count); pt(p->next); } int main() { FILE *fp; int b,i; char a[20],ch; struct node *root; i=0;b=0; for(i=0;i<20;i++) a[i]=0;//初期化 i=0; fp=fopen("data1.txt","r"); if(fp==NULL)//ファイルを開く return; while((ch=fgetc(fp)) != EOF){//文字の読み込み if(!((97<=ch)&&(ch<=122)&&(65<=ch)&&(ch<=90))){//英字以外の時 b=b+1; if(b==0)//初期のみ root=new(a); else//それ以降 in(root,a); for(i=0;i<20;i++){//初期化 a[i]=0; i=0; } } else{//英文字の時 a[i]=ch; i=i+1; } } pt(root);//出力関数へ fclose(fp); }

  • 双方向リストについて

    *prevは前の要素へのポインタ *nextは後ろの要素へのポインタ typedef struct list_t { char line[256]; struct list_t *prev; struct list_t *next; } LIST; 削除処理 *pが削除する要素 delete_line(LIST *p) { p->prev->next = p->next; p->next->prev = p->prev; free(p) } *pが挿入する要素 *cが挿入する場所 insert_line(LIST *c, LISt *p) { /*両隣へポインターをつなぐ*/ p->prev = c->prev; p->next = c; /*両隣のポインターをつなぎ換える*/ c->prev->next = p; c->prev = p; } これは、ある本に書かれていたものなのですが、どうしても、理解ができません。図を描きながら追ってみたのですが、cは、挿入する場所を表しているのですが、図で描こうにもどこがその場なのかが、わかりません。あと挿入処理のところでpやcが代入されていますが、pやcは、どこを表しているのですか?この本の説明がおかしいのでしょうか?それとも私の考え方が違うのでしょうか・・・。ご指導いただければありがたいです。

  • リスト構造のプログラミング

    #include<stdio.h> #include<stdlib.h> typedef struct number{ float x; struct number *next; }Num; void append_list(Num **, float); int main(void) { Num *start,*p; float i,d; start=NULL; for(i=0.0;i<10.0;i++){ append_list(&start,i); } p=start; while(p!=NULL){ printf("%f\n",p->x); p=p->next; } p=start; while(p !=NULL){ Num *q; q=p; p=p->next; free(q); } return 0; } void append_list(Num **s, float n) { Num *end, *new; if(*s==NULL){ *s=(Num *)malloc(sizeof(Num)*1); (*s)->x=n; (*s)->next=NULL; return; }end=(*s); while(end->next !=NULL){ end=end->next; } new=(Num *)malloc(sizeof(Num)*1); new->x=n; new->next=NULL; end->next=new; } 0~9までの数値を順番に追加してリスト構造のデータ構造で 保存するプログラミングを作ったのですが、これにキーボード から入力した1つの実数(0~9)を数値の順序を乱さないよう にその数値を持つ要素を追加するにはどうすればよいのでしょうか?

専門家に質問してみよう