ページ 11

キューについて

Posted: 2011年12月07日(水) 15:05
by Ryo
キューを実現する構造体
typedef struct {
int max; /* キューのサイズ */
int num; /* 現在の要素数 */
int front; /* 先頭要素カーソル */
int rear; /* 末尾要素カーソル */
int *que; /* キュー(の先頭要素へのポインタ) */
} Queue;

が定義されており、デキューとエンキューする関数を作らないといけないでですが、
剰余演算子%を使えとのことなのですが、わからず困っています。

int QueueEnque(Queue *q, int x)
int QueueDeque(Queue *q, int *x)
このような関数はどのように作ればよいのでしょうか

Re: キューについて

Posted: 2011年12月07日(水) 17:48
by non
柴田望洋氏の「アルゴリズムとデータ構造」から出題された問題だと思います。
http://www.bohyoh.com/Books/CalgoA/index.html
本屋または図書室に行って、上記本を見つけ、114ページを開いてください。

金がないか急ぐのでしたら、上記HPの演習問題の解答から演習4-3か演習4-4、演習4-5を解析してみてください。
ヒントになると思います。

[編集]
ごめんなさい。プログラムを見てみたら、%演算子がどこにも使われていません。
何のためにつかえという指示でしたか?

Re: キューについて

Posted: 2011年12月07日(水) 17:55
by asd
Ryo さんが書きました: 剰余演算子%を使えとのことなのですが、わからず困っています。
とのことなので、剰余演算子の使いどころだけが分からないと仮定して回答します。

キューのデータを入れるポインタは最大でmax個の要素を持つ配列になるので、
maxが10だとした場合、図示すると以下のような感じになります。

que  [ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
front  ↑0
rear   ↑0
num 0

ここに0~9までの数値を順番にエンキューすると、

que  [0][1][2][3][4][5][6][7][8][9]
front  ↑0
rear                   ↑9
num 10

こうなります。
ここで5回デキューすると、

que  [0][1][2][3][4][5][6][7][8][9]
front           ↑5
rear                   ↑9
num 5

こうなります。
さて、ここで再びエンキューをするとき、そのデータはどこに入れればいいでしょうか?
単純にrearに1加算したところに入れてしまうとque[10]を指してしまい範囲外になってしまいます。
今現在que[0]~que[4]はデキューされて使用されていない領域なので、que[0]から再び値を入れていけばいいことになります。
(frontやrearの値は0→1・・・→9→0→1・・・のように0~9を繰り返せばいいわけです)

ここでif文を使ってfrontやrearが9を超えていたら0に戻すという方法もありますが、
frontやrearに対してmaxの剰余を取るという方法もあります

コード:

front = (front+1)%max;
こうしておくとfrontの値はmax以上にはなりません。

そういうことを聞きたいわけではないという場合には、何が分からないのかを再度聞いてもらえたらと思います。

[追記]
キュー用の配列をローテート(末尾まで使い切ったら先頭から再利用)するつもりで上記を説明しましたが、nonさんが挙げているページのプログラムだと剰余演算子を使わないですね(汗)
とりあえずは質問者さんの反応待ちということで。

Re: キューについて

Posted: 2011年12月07日(水) 18:11
by non
asd さんが書きました:frontやrearに対してmaxの剰余を取るという方法もあります

コード:

front = (front+1)%max;

なるほどね。それ、当たりでしょう。

q->gue[(q->rear++)%q->max]=x;

ってなりますか。

[編集]
インクリメント演算子ではまずいですか。それに代入しないと。
q->rear=(q->rear + 1) % q->max;
q->gue[q->rear]=x;
[ご指摘により編集]
q->que[q->rear]=x;

Re: キューについて

Posted: 2011年12月08日(木) 10:19
by asd
non さんが書きました: [編集]
インクリメント演算子ではまずいですか。それに代入しないと。
q->rear=(q->rear + 1) % q->max;
q->gue[q->rear]=x;
確かにそうですね。
数回やる分には大丈夫ですが、何度も繰り返すとq->rearがいずれは上限を超えちゃいますからね。
#個人的にはqueがgueになっているのが気になってます。

Re: キューについて

Posted: 2011年12月09日(金) 12:22
by ryo
剰余演算子を使ってプログラムできました。

みなさんありがとうございした。

Re: キューについて

Posted: 2011年12月09日(金) 12:47
by beatle
フォーラムルールには
また、解決した時は、「解決しました」とだけ言って去らず、ソースコードや解決した方法を明記して下さい。
と書いてありますから、その通りにしてください。

Re: キューについて

Posted: 2011年12月09日(金) 17:44
by asd
ryo さんが書きました:剰余演算子を使ってプログラムできました。

みなさんありがとうございした。
beatleさんも指摘していますが、どのようなプログラムを書いたのかを教えていただかないと、
同じような問題で困っているかたがこのスレを見たときに困ってしまいます。

同じような問題で困っている方を助けるつもりで是非解決方法を書いてください。
#結局私の推測が正しいのかどうか気になって仕方ないです