1時間ごとに更新!Amazon.co.jpで今売れている本トップ100   掲示板ランキング



掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板1

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧

No.5867

構造体のソート
投稿者---ぺーぺー(2006/06/20 15:23:47)


cの超初心者です。くだらない質問かもしれませが助けてください。
txtファイルからデータを読込み、以下の構造体を使います。
○構造体でスコア順にソートするプログラム
 typedef struct {
int iSeq; //順位
char cName[12]; //プレイヤー
int iScr[3]; //スコア1、2、3
int iTotal; //合計スコア
 } ST_BOWL;
順位以外は配列で求めれました。
○現在の問題点
 ・順位を求めることができない(スコアが被った時含む)。
 ・順位が分からないので昇順にソートできない。
完成形は
順位  名前  スコア1 スコア2 スコア3 合計
<1> スズキ  100   200   250   550
<2> トヨタ   150   100   100   350
<2> ホンダ   50   150   150   350
<4> ニッサン 50   100   80    230


といった感じです。
txtファイルには昇順で入っていないため、順位をつけて構造体の行ごとにソートしようとしています。
問題点の解決法など分かる方おられましたら助けてくださいm(__)m



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:構造体のソート 5868 Yuki 2006/06/20 15:27:53
<子記事> Re:構造体のソート 5904 kz3 2006/06/21 16:54:30


No.5868

Re:構造体のソート
投稿者---Yuki(2006/06/20 15:27:53)


>○現在の問題点
> ・順位を求めることができない(スコアが被った時含む)。

なぜ順位を求めることができないのですか?



この投稿にコメントする

削除パスワード

No.5870

Re:構造体のソート
投稿者---ぺーぺー(2006/06/20 15:32:07)


>なぜ順位を求めることができないのですか?
現在合計を使って求めていますが、ソートはできても順位として反映できない感じです。



この投稿にコメントする

削除パスワード

No.5871

Re:構造体のソート
投稿者---Yuki(2006/06/20 15:34:36)


>>なぜ順位を求めることができないのですか?
>現在合計を使って求めていますが、ソートはできても順位として反映できない感じです。

ソートができていれば、上から1位、2位、3位とつけるだけのような
気がしますが?

ソースを提示していただければ、問題点がわかるかもしれません。



この投稿にコメントする

削除パスワード

No.5874

Re:構造体のソート
投稿者---kz3(2006/06/20 16:24:47)


>ソートができていれば、上から1位、2位、3位とつけるだけのような気がしますが?

順位   名前      スコア1 スコア2 スコア3 合計
<1>  スズキ    100     200     250     550
<2>  トヨタ    150     100     100     350
<2>  ホンダ    50      150     150     350
<4>  ニッサン  50      100     80      230

合計が被ったときは同順として表示するんだと思いますが、被った数をあれこれすればいいだけでは?

何故、2位2社続いた次の順位は4位から始まるのか、
ぺーぺーさんがそう考えた( 計算した )手順をコンピュータに教えてあげればいいです。
現在の順位から n 社、同じ合計の会社が続いたら、次の順位は現在の順位 + n で求まる。
# 問題なのはそういうことじゃなくて?
# 合計が同じなのに、「ホンダ」の方が「トヨタ」よりも上にきてしまうとか?



この投稿にコメントする

削除パスワード

No.5890

Re:構造体のソート
投稿者---ぺーぺー(2006/06/21 09:59:03)


><pre><font color=brown>>ソートができていれば、上から1位、2位、3位と つけるだけのような気がしますが?</font>
 合計が被ったときは同順として表示するんだと思いますが、被った数をあれこ れすればいいだけでは?

 返信送れて大変申し訳ございませんm(__)m
 おっしゃる通りなのですが、「あれこれ」に苦労しています。
 カウントを2つ持たせてやろうとか色々考えたのですが、頭打ちの状態です。
 その前に今の状況だとソートも怪しい感じです。



この投稿にコメントする

削除パスワード

No.5891

Re:構造体のソート
投稿者---shu(2006/06/21 10:10:58)


> 返信送れて大変申し訳ございませんm(__)m
> おっしゃる通りなのですが、「あれこれ」に苦労しています。
> カウントを2つ持たせてやろうとか色々考えたのですが、頭打ちの状態です。
> その前に今の状況だとソートも怪しい感じです。

↑の文章は、返信する側からみて、有効な返信をするための、有効な情報にはなりません。


この投稿にコメントする

削除パスワード

No.5893

Re:構造体のソート
投稿者---kz3(2006/06/21 10:31:43)


>何故、2位が2社続いた次の順位は4位から始まるのか、

これに答えられれば、そのままコードに起こすだけだと思いますが。
何の考えもなしに、2位2社続いた次の順位は4位から始まるような結果を望んだのですか?

まぁ普段の生活では特別、説明しなくても「常識でしょ?」で通じることもありますが、
コンピュータはその「常識」を順序だてて説明してあげないと分からないのです。

だから、人( 自分も含む )に説明できないことは、コンピュータにやらせることはできません。
( 出来る人もいるかも知れないけど、私は出来ません )




この投稿にコメントする

削除パスワード

No.5889

Re:構造体のソート
投稿者---ぺーぺー(2006/06/21 09:48:33)


>ソートができていれば、上から1位、2位、3位とつけるだけのような
>気がしますが?
>
>ソースを提示していただければ、問題点がわかるかもしれません。

返信遅れて大変申し訳ございませんm(__)m
その順位のつけ方に考えが回らず苦労しています。
ソートの部分は以下のようにバブルソートを用いて行っております。(クイックソートはよく分かりませんでした)

○ib・・・構造体の行数、ST_BOWL[ib].iTotal ・・・スコアの合計を格納する構造体

id = ib;   // 構造体の行数を代入
do {
  iflag = 0;
  for (ib=0; ib<id-1; ib++) { // 配列の最初から最後までループ
   // 隣接する行より数が大きいか
   if (ST_BOWL[ib].iTotal > ST_BOWL[ib+1].iTotal) { ic = ST_BOWL[ib].iTotal;  // icに旧最小値を退避
     ST_BOWL[ib].iTotal = ST_BOWL[ib+1].iTotal;// 新最小値を格納
     ST_BOWL[ib+1].iTotal = ic; // 新最小値の隣に旧最小値を格納
     iflag = 1; // 入替え済のフラグ
    }
  }
} while (iflag == 1); // 入替え完了後抜ける

このような感じです。これだと合計がソートされるだけなので、目的の構造体の行ごとソートするというのができません。
よろしかったらアドバイスお願いいたします。



この投稿にコメントする

削除パスワード

No.5892

Re:構造体のソート
投稿者---Yuki(2006/06/21 10:29:21)


>このような感じです。これだと合計がソートされるだけなので、目的の構造体の行ごとソートするというのができません。

やはり順位の前に、ソートが未完のようですね。

iTotalしか入れ替えていないのですから、合計のみソートされますよね。
他のメンバもソートする必要があるのでは?

ちなみに、ソートは昇順ですか?降順ですか?

ソート前の構造体のデータと、ソート後の構造体のデータをprintf等で表示して
比較してみてください。



気になったのですが、iflagは必要ありますか?
もともとのデータがソートする必要がなかったら無限ループに陥るような・・・。




この投稿にコメントする

削除パスワード

No.5895

Re:構造体のソート
投稿者---ぺーぺー(2006/06/21 11:38:51)


>iTotalしか入れ替えていないのですから、合計のみソートされますよね。
>他のメンバもソートする必要があるのでは?

ありがとうございます。うまくソートできました。

>気になったのですが、iflagは必要ありますか?
>もともとのデータがソートする必要がなかったら無限ループに陥るような・・・。

この方法しか思い浮かばなかったもので・・・ 実行してみると今のところ問題なく動作しているので、今後問題が発生すれば考えたいと思います。

あとは順位の付け方ですが、

id = ib;   // 構造体の行数を代入
do {
  iflag = 0;
  for (ib=0; ib>id-1; ib++) { // 配列の最初から最後までループ
    if (ST_BOWL[ib].iTotal > ST_BOWL[ib+1].iTotal) {

     ic = ST_BOWL[ib].iTotal;  // icに旧最小値を退避
     //同様の処理を名前、スコア、平均でも行う

     ST_BOWL[ib].iTotal = ST_BOWL[ib+1].iTotal;// 新最小値を格納
     //同様の処理を名前、スコア、平均でも行う

     ST_BOWL[ib+1].iTotal = ic; // 新最小値の隣に旧最小値を格納
     //同様の処理を名前、スコア、平均でも行う

     iflag = 1; // 入替え済のフラグ
    }
  }
} while (iflag == 1); // 入替え完了後抜ける

for(ib=0; ib<id; ib++) {
  printf(" %d ", ST_BOWL[ib].iTotal);
  //同様の処理を名前、スコア、平均でも行う
 }
 return 0;
}
といった流れの中で、どのタイミングで順位付けをするのが適当か、見つけられません。よろしければご指導お願いいたします。


この投稿にコメントする

削除パスワード

No.5897

Re:構造体のソート
投稿者---kz3(2006/06/21 12:12:25)


全角インデントでなくて、HTMLが使えるのでツールで変換してくれると読みやすいのですが、まぁいいでしょう...

>     ic = ST_BOWL[ib].iTotal;  // icに旧最小値を退避
>     //同様の処理を名前、スコア、平均でも行う
>
>     ST_BOWL[ib].iTotal = ST_BOWL[ib+1].iTotal;// 新最小値を格納
>     //同様の処理を名前、スコア、平均でも行う
>
>     ST_BOWL[ib+1].iTotal = ic; // 新最小値の隣に旧最小値を格納
>     //同様の処理を名前、スコア、平均でも行う

構造体の一括代入を有効に使いましょう。

>
>for(ib=0; ib<id; ib++) {		
>  printf("    %d ", ST_BOWL[ib].iTotal);
>  //同様の処理を名前、スコア、平均でも行う
> }

最小値を配列の先頭にもってきて、先頭から順に表示するんですね?

>といった流れの中で、どのタイミングで順位付けをするのが適当か、見つけられません。

ミカン狩りに出かけて、ミカンを100個取ってきて、
大きいミカンから小さいミカンに1から順番に番号を付けるのと、
同じ方法でやればいいです。




この投稿にコメントする

削除パスワード

No.5898

Re:構造体のソート
投稿者---Yuki(2006/06/21 12:28:36)


>といった流れの中で、どのタイミングで順位付けをするのが適当か、見つけられません。よろしければご指導お願いいたします。

構造体に、合計メンバの昇順でデータが格納されていませんか?
それに1位、2位、3位と順位をつけるのはちょっと技が必要そうですね。

合計メンバの降順でデータを格納し、出力する際に順位付けをしてみては
いかがでしょう?



この投稿にコメントする

削除パスワード

No.5901

Re:構造体のソート
投稿者---ぺーぺー(2006/06/21 14:59:32)


皆さんのおかげで、何とかソートもできました。
しかし、ようやく完成したかと思ったら、新たな問題が見つかりました。
〔樵亜Ε好灰△箸皀如璽燭虜蚤臙佑防充┐全て合わされてしまい、うまく表示できません。(例:<1>ニッサンの次にトヨタが来ると、トヨタンになる。<2>スコアの90が900になる。)
恐らく初期化がうまくいっていないと考えているのですが、原因がわかりません。
▲好灰■海帽膩廚かぶってしまいうまく表示できません。

○自作ヘッダファイルで宣言しています。
○int bowl_GetWord(FILE *fp, char *buf)という関数でファイルデータを正常に読込めば0、EOFの時は-1を返すという判定をしています。

かなり見難いソースですが、見ていただける方いたらご指導お願いいたします。


<pre>#include &quot;head.h&quot;

int main(void)
{
if ((fp = fopen(&quot;s_sort.txt&quot;, &quot;r&quot;)) == NULL) { // ファイルオープン
printf(&quot;Input File Open Error!!\n&quot;);
exit(1);
}

printf(&quot;順位 PLAYER SCORE1 SCORE2 SCORE3 TOTAL AVE \n&quot;);

for ( ; ; ) {

ijudge = bowl_GetWord(fp, chbuf); // 戻り値を受け取る

if (ijudge == 0) { // 戻り値が0の場合

// 名前

if (icnt == 0) { // 名前の構造体に格納

strcpy(ST_BOWL[ib].cName,chbuf);

icnt++;
}

// スコア

else if (icnt == 1) { // 1つめのスコアの構造体に格納
ibuf = atoi(chbuf);
ST_BOWL[ib].iScr[1] = ibuf;

icnt++;
}

else if (icnt == 2) { // 2つめのスコアの構造体に格納
ibuf = atoi(chbuf);
ST_BOWL[ib].iScr[2] = ibuf;

icnt++;
}

else { // 3つめのスコアの構造体に格納
ibuf = atoi(chbuf);
ST_BOWL[ib].iScr[3] = ibuf;

ib++; // 構造体の次の行に移る
icnt = 0; // カウントの初期化
}

strcpy(chbuf,&quot;&quot;); // bufの初期化
continue;
}

// 最後のスコア

else { // 戻り値が0以外の場合
/*ibuf = atoi(chbuf);
ST_BOWL[ib].iScr[3] = ibuf;

ib++; // 構造体の次の行に移る
icnt = 0; */ // カウントの初期化
break;
}
}

ie = ib;

for (ib=0; ib&lt;ie; ib++) {
// 合計
ST_BOWL[ib].iTotal = ST_BOWL[ib].iScr[1] + ST_BOWL[ib].iScr[2]/* + ST_BOWL[ib].iScr[3]*/;

// 平均
ST_BOWL[ib].fAve = (float)ST_BOWL[ib].iTotal / 3;
}


// ソート

id = ib; // 構造体の行数を代入

do {

iflag2 = 0;

for (ib=0; ib&lt;id-1; ib++) { // 配列の最初から最後までループ

if (ST_BOWL[ib].iTotal &lt; ST_BOWL[ib+1].iTotal) { // 隣接する行がの数が大きいか

strcpy(chn, ST_BOWL[ib].cName); // 名前、スコア、合計、平均を別のメモリに退避
is1 = ST_BOWL[ib].iScr[1];
is2 = ST_BOWL[ib].iScr[2];
is3 = ST_BOWL[ib].iScr[3];
it = ST_BOWL[ib].iTotal;
fav = ST_BOWL[ib].fAve;

strcpy(ST_BOWL[ib].cName, ST_BOWL[ib+1].cName); // 新最小値を格納
ST_BOWL[ib].iScr[1] = ST_BOWL[ib+1].iScr[1];
ST_BOWL[ib].iScr[2] = ST_BOWL[ib+1].iScr[2];
ST_BOWL[ib].iScr[3] = ST_BOWL[ib+1].iScr[3];
ST_BOWL[ib].iTotal = ST_BOWL[ib+1].iTotal;
ST_BOWL[ib].fAve = ST_BOWL[ib+1].fAve;

strcpy(ST_BOWL[ib+1].cName, chn); // 新最小値の隣に旧最小値を格納
ST_BOWL[ib+1].iScr[1] = is1;
ST_BOWL[ib+1].iScr[2] = is2;
ST_BOWL[ib+1].iScr[3] = is3;
ST_BOWL[ib+1].iTotal = it;
ST_BOWL[ib+1].fAve = fav;

iflag2 = 1; // 入替え済のフラグ
}

}

} while (iflag2 == 1); // 入替え完了後抜ける

for (ib=0; ib&lt;id; ib++) { // 行数分結果表示


ST_BOWL[ib].iSeq = icnt2;

printf(&quot;&lt;%3d&gt; &quot;, ST_BOWL[ib].iSeq);
printf(&quot;[%-12s ] &quot;, ST_BOWL[ib].cName);
printf(&quot; %d &quot;, ST_BOWL[ib].iScr[1]);
printf(&quot; %d &quot;, ST_BOWL[ib].iScr[2]);
printf(&quot; %d &quot;, ST_BOWL[ib].iScr[3]);
printf(&quot; %d &quot;, ST_BOWL[ib].iTotal);
printf(&quot; %5.1f\n&quot;,ST_BOWL[ib].fAve);


if (ST_BOWL[ib].iTotal == ST_BOWL[ib+1].iTotal) {
icnt2;
icnt3++;
}

else {
icnt2 = icnt2 + icnt3;
}

}
return 0;
}




この投稿にコメントする

削除パスワード

No.5902

Re:構造体のソート
投稿者---Yuki(2006/06/21 15:37:43)


ざっと見た感じ、この部分のソースには問題なさそうです。
ソート前の構造体は、ちゃんとデータが入っていますか?

>恐らく初期化がうまくいっていないと考えているのですが、原因がわかりません。

初期化の部分が無いので、原因がわかりません。




この投稿にコメントする

削除パスワード

No.5903

Re:構造体のソート
投稿者---ぺーぺー(2006/06/21 15:58:45)


>ソート前の構造体は、ちゃんとデータが入っていますか?
 スコア3の部分だけ合計する時、合計に上書きされてしまいます。
>初期化の部分が無いので、原因がわかりません。
 strcpy(chbuf,""); という形で、メイン関数のスコア3を求めたあとに、ファイルから読取ったデータを格納している、chbufを初期化しているつもりでしたが・・・
ファイルからデータを読取るbowl_GetWordという関数のソースを載せますので、気づかれた点あればご指摘お願いいたします。 

 
<pre>&lt;pre&gt;int bowl_GetWord(FILE *fp, char *buf)
{
  
  for ( ; ; ) {
      
    ch = fgetc(fp);   // 1文字ずつ読込む

    if (feof(fp) != 0) {  // ファイルの終端か
      return -1;      // -1を返す
    }

    // デリミタか
    if (ch == 32 || ch == '\t' || ch == '\n' || ch == ',' || ch == ':' || ch == ';') { 
      if (iflag == 1) { // フラグあれば0を返す
        ii=0;
        return 0;
      }
    }
    
    else {
      chbuf[ii] = ch;  // chbufに代入
      ii++;
      iflag = 1;      // フラグ1を持たせる
    }
  }
}
&lt;/pre&gt;
</pre>






この投稿にコメントする

削除パスワード

No.5906

Re:構造体のソート
投稿者---Yuki(2006/06/21 17:29:30)


初歩的な部分を見落としていました。

ST_BOWL[ib].iScr[1]
ST_BOWL[ib].iScr[2]
ST_BOWL[ib].iScr[3]

配列のインデックスはあっていますか?


私もkz3さんに同意します。




この投稿にコメントする

削除パスワード

No.5915

Re:構造体のソート
投稿者---ぺーぺー(2006/06/22 09:37:05)


kz3さん、Yukiさん、他皆さん、ご迷惑お掛けして申し訳ありませんでした。
今後気をつけたいと思います。
お二方のおかげで無事起動するようになりました。
多忙の中お付き合い頂き、ありがとうございました。


この投稿にコメントする

削除パスワード

No.5904

Re:構造体のソート
投稿者---kz3(2006/06/21 16:54:30)


ソースのHTML変換に成功していることを「確認画面へ」で確認されてから投稿してください...

失敗したのを正すのは回答者側の負担ですか?


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧





掲示板提供:(有)リアル・インテグリティ