マージと基数変換について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
リヴァイアサン

マージと基数変換について

#1

投稿記事 by リヴァイアサン » 14年前

2題協力をお願いします
字数が多くなるので分けます

まず「昇順に並んだ適当な整数で初期化された要素数5個の配列を2個用意する。別に要素数10個の配列を用意して、その要素が前の2個の配列中の要素を混ぜ合わせて昇順に並べたものを作れ、ただし2個の配列と要素数を引数としてそれらの配列をマージした結果を返す関数を定義せよ」
という問題で関数を使わないプログラムを以下で書いたのですが

コード:

#include <stdio.h>

main(){
  int a[5]={1,2,3,4,5};
  int b[5]={1,2,3,4,5};
  int c[10];
  int i, x, y, z, x1, y1, z1;
  for(i=0; i<10; i++){
    z=999;
    x1=999;
    for(x=0; x<5; x++){
      if(a[x]<z){
	z=a[x];
	y1=x;
      }
    }
    for(y=0; y<5; y++){
      if(b[y]<x1){
	x1=b[y];
	z1=y;
      }
    }
    if(z<=x1){
      c[i]=z;
      a[y1]=99999;
    }
    else{
      c[i]=x1;
      b[z1]=99999;
    }
  }
  for(i=0; i<10; i++)
    printf("[%d]=%d\n", i, c[i]);
}
上記プログラムの整数型配列cを関数を使って書き直したときどのようにしたらいいのかがわからないのでアドバイスをお願いします

リヴァイアサン

Re: マージと基数変換について

#2

投稿記事 by リヴァイアサン » 14年前

次の問いは
「10進数nをm桁のd進数に変換することを考える。d進数の各桁の数値をa[m-1],a[m-2],,,,,a[0]として、それらの値を計算して桁数を返す関数を作成せよ。なおm桁で表せないときは−1を返すようにせよ」
という問題なんですが問題のいっている意味がわからなくてプログラムが作れないので
解りやすい説明が出来る方はお願いします

box
記事: 2002
登録日時: 14年前

Re: マージと基数変換について

#3

投稿記事 by box » 14年前

リヴァイアサン さんが書きました: 昇順に並んだ適当な整数で初期化された要素数5個の配列を2個用意する。
その、適当な整数に例えば100000があったとき、正しく動きますか?
コード中の999とか99999とかいう値は、何のためのものですか?

関数化する前に、まずは2個の配列の中身がどういう値であっても
正しく動くコードを書くことが先決でありましょう。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

box
記事: 2002
登録日時: 14年前

Re: マージと基数変換について

#4

投稿記事 by box » 14年前

リヴァイアサン さんが書きました: 次の問いは
別のトピックを立てた方がよかったと思います。まあそれはさておき、
リヴァイアサン さんが書きました: 10進数nをm桁のd進数に変換することを考える。
何か具体的なケースを考えてみたらどうでしょうか。例えば、

10進数の10を5桁の2進数に変換することを考える。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

リヴァイアサン

Re: マージと基数変換について

#5

投稿記事 by リヴァイアサン » 14年前

上はミスですすいません


その、適当な整数に例えば100000があったとき、正しく動きますか?
コード中の999とか99999とかいう値は、何のためのものですか?
関数化する前に、まずは2個の配列の中身がどういう値であっても
正しく動くコードを書くことが先決でありましょう。

>>マージの参考プログラムをネットで検索してみまして
それを参考にして作ったので値はそのままにしました
いつもはそこまで大掛かりな数字が”適当な”に該当してないので差して問題ないと思いまして‥

リヴァイアサン

Re: マージと基数変換について

#6

投稿記事 by リヴァイアサン » 14年前

別のトピックを立てた方がよかったと思います。まあそれはさておき、

>>逆に迷惑になるかと思ったのですが裏目にでましたか‥

何か具体的なケースを考えてみたらどうでしょうか。例えば、

10進数の10を5桁の2進数に変換することを考える。

>>始めはそのようなプログラムを書いていってへんかさせていくという形でということでしょうか?

box
記事: 2002
登録日時: 14年前

Re: マージと基数変換について

#7

投稿記事 by box » 14年前

さして問題ない、という風に考えて本当にいいのでしょうか。
出題文に

>昇順に並んだ適当な整数

と明記しているということは、それが100000であってもいっこうに差し支えない、
ということですよね。ふつうは、そういう風に考えると思いますが。

2つの配列をマージするとき、999とか99999とかのような特殊な数値が
コード中に登場しなくてもいいようなアルゴリズムを考えてみてはどうでしょうか。
そもそも、コンピューターを使わずに手でマージするとき、どういう風にしますか?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

リヴァイアサン

Re: マージと基数変換について

#8

投稿記事 by リヴァイアサン » 14年前

>昇順に並んだ適当な整数

と明記しているということは、それが100000であってもいっこうに差し支えない、
ということですよね。ふつうは、そういう風に考えると思いますが。

>>すいません、上でいい忘れがありまして
適当な数自体はこちらで勝手に決めていいものなので自分が100000を今使わない以上関係性はないということです

box
記事: 2002
登録日時: 14年前

Re: マージと基数変換について

#9

投稿記事 by box » 14年前

リヴァイアサン さんが書きました: 10進数の10を5桁の2進数に変換することを考える。

>>始めはそのようなプログラムを書いていってへんかさせていくという形でということでしょうか?
いくつか具体例を考えていくうちに、一般的な法則が見えてくるのではないかな、と思ったりしています。
その法則が見えたら、n, m, d をどのように変化させても正しく動くコードが書けるはずです。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

リヴァイアサン

Re: マージと基数変換について

#10

投稿記事 by リヴァイアサン » 14年前

いくつか具体例を考えていくうちに、一般的な法則が見えてくるのではないかな、と思ったりしています。

>>最初の方が終わり次第何件か考えてみます

box
記事: 2002
登録日時: 14年前

Re: マージと基数変換について

#11

投稿記事 by box » 14年前

リヴァイアサン さんが書きました: >>すいません、上でいい忘れがありまして
適当な数自体はこちらで勝手に決めていいものなので自分が100000を今使わない以上関係性はないということです
まあ、それにしたところで、999とか99999とかが出てこないようなコードが書けるはずです。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

リヴァイアサン

Re: マージと基数変換について

#12

投稿記事 by リヴァイアサン » 14年前

まあ、それにしたところで、999とか99999とかが出てこないようなコードが書けるはずです。
>>一段落したら書き直します

box
記事: 2002
登録日時: 14年前

Re: マージと基数変換について

#13

投稿記事 by box » 14年前

最初の問題のヒント。

初期状態では、a[]の着目位置はa[0], b[]の着目位置はb[0], c[]のセット位置はc[0]。
a[]とb[]の着目位置どうしを比べる。a[0]とb[0]とではa[0]の方が大きくないので、a[]の着目位置の値a[0]をc[]のセット位置c[0]に代入する。
a[]の着目位置を1つ進めてa[1]にする。
c[]のセット位置を1つ進めてc[1]にする。

a[]とb[]の着目位置どうしを比べる。a[1]とb[0]とではb[0]の方が大きくないので、b[]の着目位置の値b[0]をc[]のセット位置c[1]に代入する。
b[]の着目位置を1つ進めてb[1]にする。
c[]のセット位置を1つ進めてc[2]にする。

これを繰り返していくと、いつかはa[]やb[]の着目位置が要素数5に到達します。到達した方の配列はそれ以上参照しなくてよくなります。
そして、着目位置が要素数5に到達していない方の配列の残り分をc[]に代入すれば、マージが完了します。
999や99999という特殊な値はどこにも登場しません。
最後に編集したユーザー box on 2011年7月17日(日) 01:44 [ 編集 1 回目 ]
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

リヴァイアサン

Re: マージと基数変換について

#14

投稿記事 by リヴァイアサン » 14年前

最初の問題のヒント。

初期状態では、a[]の着目位置はa[0], b[]の着目位置はb[0], c[]のセット位置はc[0]。
a[]とb[]の着目位置どうしを比べる。a[0]とb[0]とではa[0]の方が大きくないので、a[]の着目位置の値a[0]をc[]のセット位置c[0]に代入する。
a[]の着目位置を1つ進めてa[1]にする。
c[]のセット位置を1つ進めてc[1]にする。

a[]とb[]の着目位置どうしを比べる。a[1]とb[0]とではb[0]の方が大きくないので、b[]の着目位置の値b[0]をc[]のセット位置c[1]に代入する。
b[]の着目位置を1つ進めてb[1]にする。
c[]のセット位置を1つ進めてc[2]にする。

これを繰り返していくと、いつかはa[]やb[]の着目位置が要素数5に到達します。到達した方の配列はそれ以上参照しなくてよくなります。
そうすると、着目位置が要素数5に到達していない方の配列の残り分をc[]に代入すれば、マージが完了します。
999や99999という特殊な値はどこにも登場しません。

>>よくわからないのですが、プログラム全体を書き直せという感じでいいのでしょうか?
上のじゃ、関数に書き換えられないという風にとらえていいのでしょうか?

box
記事: 2002
登録日時: 14年前

Re: マージと基数変換について

#15

投稿記事 by box » 14年前

リヴァイアサン さんが書きました: >>よくわからないのですが、プログラム全体を書き直せという感じでいいのでしょうか?
上のじゃ、関数に書き換えられないという風にとらえていいのでしょうか?
ロジックを見直した方が、(100000に対応できない、というバグを含まない)より堅牢なコードになるのではないかな、
と思っています。
まあ、別に命令しているわけではありませんけれど。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

リヴァイアサン

Re: マージと基数変換について

#16

投稿記事 by リヴァイアサン » 14年前

ロジックを見直した方が、(100000に対応できない、というバグを含まない)より堅牢なコードになるのではないかな、
と思っています。
まあ、別に命令しているわけではありませんけれど。

>>限りなく完璧なプログラム自体目指している訳ではないので
それなりのものでいいのですが‥‥
一応考えてはみますが‥‥

リヴァイアサン

Re: マージと基数変換について

#17

投稿記事 by リヴァイアサン » 14年前

コード:

 
int merge(int a[], int b[], int m){
  int c[10], i;
  for(i=0; i<10; i++){
    if(a[i]<=b[i]){
      a[i]=c[i];
      b[i]=c[i+1];
    }
  }
} 

こんな感じかと思いやってみたら出来ないんですがif文の中がおかしいんですよね?
改善点がよくわからないのですが

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: マージと基数変換について

#18

投稿記事 by h2so5 » 14年前

a=c;

これは明らかにおかしいでしょう。
aは書き換えてはいけないし、cは初期化されていません。

リヴァイアサン

Re: マージと基数変換について

#19

投稿記事 by リヴァイアサン » 14年前

これは明らかにおかしいでしょう。
>>ですよねー…。

box
記事: 2002
登録日時: 14年前

Re: マージと基数変換について

#20

投稿記事 by box » 14年前

リヴァイアサン さんが書きました:

コード:

int merge(int a[], int b[], int m){

こんな感じかと思いやってみたら出来ない
引数mの意味は何でしょうか?また、関数の中で使っていないですね。
リヴァイアサン さんが書きました: 改善点がよくわからないのですが
私が例示したロジックにもしも従うならば、
1)a[]の着目位置
2)b[]の着目位置
3)c[]のセット位置
を覚えておくための変数がそれぞれ必要です。これは理解できますか?

それから、2つの配列を手でマージするとき、どういう風にしますか?
手でマージする手順を忠実にコードに置き換えればいいのです。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

non
記事: 1097
登録日時: 14年前

Re: マージと基数変換について

#21

投稿記事 by non » 14年前

リヴァイアサン さんのマージのプログラムは課題として合格点がもらえるものではありません。
データは整列されているのに、最小値法で探していますし・・・
boxさんの説明に従って、書き直してください。

999などを使うのはファイルから読み込む場合、データの個数がわからず、まだデータの範囲が与えられているときに
MAX_VALUEとして使う方法です。今回はデータの個数が決められているので使いません。
仮に、データが
int a[]={10,20,30,40,50,999};
int b[]={15,25,27,28,70,999};
のように最後にMAX_VALUEが与えられているときになら使えます。

もうひとつの課題は、この課題が終わってから、別スレにしませんか。
non

リヴァイアサン

Re: マージと基数変換について

#22

投稿記事 by リヴァイアサン » 14年前

引数mの意味は何でしょうか?また、関数の中で使っていないですね。

>>一行消してました。どのみち意味ありませんでしたけど

私が例示したロジックにもしも従うならば、
1)a[]の着目位置
2)b[]の着目位置
3)c[]のセット位置
を覚えておくための変数がそれぞれ必要です。これは理解できますか?

>>余分に3つ変数宣言しろということですね

それから、2つの配列を手でマージするとき、どういう風にしますか?
手でマージする手順を忠実にコードに置き換えればいいのです。

>>手でマージするとは?

リヴァイアサン

Re: マージと基数変換について

#23

投稿記事 by リヴァイアサン » 14年前

リヴァイアサン さんのマージのプログラムは課題として合格点がもらえるものではありません。
データは整列されているのに、最小値法で探していますし・・・
boxさんの説明に従って、書き直してください。

>>ウチの大学ではプログラムが通って一応の結果を残せば点数はくれるので合格点とかがそもそもありません。
上記のとおり書き直し作業してますが

999などを使うのはファイルから読み込む場合、データの個数がわからず、まだデータの範囲が与えられているときに
MAX_VALUEとして使う方法です。今回はデータの個数が決められているので使いません。

>>上でもいいましたが適当な値自体は自分個人で決めて構わないという風になっています


もうひとつの課題は、この課題が終わってから、別スレにしませんか。

>>そうさせてもらいます

non
記事: 1097
登録日時: 14年前

Re: マージと基数変換について

#24

投稿記事 by non » 14年前

>>ウチの大学ではプログラムが通って一応の結果を残せば点数はくれるので合格点とかがそもそもありません。
>>上でもいいましたが適当な値自体は自分個人で決めて構わないという風になっています

酷い大学ですね。大学に行く価値がありません。
non

リヴァイアサン

Re: マージと基数変換について

#25

投稿記事 by リヴァイアサン » 14年前

酷い大学ですね。大学に行く価値がありません。
>>そうですね、でもプログラミングを使う職につくつもりのない自分にはありがたい話です

non
記事: 1097
登録日時: 14年前

Re: マージと基数変換について

#26

投稿記事 by non » 14年前

リヴァイアサン さんを非難するつもりはありませんが、学生が大学の存在価値を決めています。
先生にやる気がないとすれば、学生にやる気がないからです。

コード:

#include <stdio.h>

int main(void){
	int a[]={10,20,30,40,50};
	int b[]={11,20,22,25,70};
	int c[10];
	int i,ia,ib,ic;
	ia=ib=ic=0;
	while(ic<10){
		if(ia<5 && ib<5){
			if(a[ia]<b[ib])
				c[ic++]=a[ia++];
			else
				c[ic++]=b[ib++];
		}
		else if(ia==5)
			c[ic++]=b[ib++];
		else
			c[ic++]=a[ia++];
	}

	for(i=0; i<10; i++)
		printf("[%d]=%d\n", i, c[i]);
}
non

リヴァイアサン

Re: マージと基数変換について

#27

投稿記事 by リヴァイアサン » 14年前

リヴァイアサン さんを非難するつもりはありませんが、学生が大学の存在価値を決めています。
先生にやる気がないとすれば、学生にやる気がないからです。

>>その通りだと思います。
ただ先生をフォローしたくはないんですが、やる気は一応持っていると思います。しかしかなりの説明が下手で自分みたいなのには伝わらないような講義をします。
ちなみに自分もやるきがないようにみえるかもしれませんが金曜からこの宿題やっててまだ寝てないです
一応それくらいは頑張ってます

コード:

#include <stdio.h>

int main(void){
	int a[]={10,20,30,40,50};
	int b[]={11,20,22,25,70};
	int c[10];
	int i,ia,ib,ic;
	ia=ib=ic=0;
	while(ic<10){
		if(ia<5 && ib<5){
			if(a[ia]<b[ib])
				c[ic++]=a[ia++];
			else
				c[ic++]=b[ib++];
		}
		else if(ia==5)
			c[ic++]=b[ib++];
		else
			c[ic++]=a[ia++];
	}

	for(i=0; i<10; i++)
		printf("[%d]=%d\n", i, c[i]);
}
[/quote]

>>参考にしてみます

リヴァイアサン

Re: マージと基数変換について

#28

投稿記事 by リヴァイアサン » 14年前

nonさんが書いてくださったこのプログラムをお借りして改めて質問なんですが
一番最初に自分が聞きたかった2個の配列と要素数を引数としてそれらの配列をマージした結果を返す関数に書きなおさないといけないのですが、関数中にc[]が入っててもいいのでしょうか?

コード:

#include <stdio.h>

int main(void){
	int a[]={10,20,30,40,50};
	int b[]={11,20,22,25,70};
	int c[10];
	int i,ia,ib,ic;
	ia=ib=ic=0;
	while(ic<10){
		if(ia<5 && ib<5){
			if(a[ia]<b[ib])
				c[ic++]=a[ia++];
			else
				c[ic++]=b[ib++];
		}
		else if(ia==5)
			c[ic++]=b[ib++];
		else
			c[ic++]=a[ia++];
	}

	for(i=0; i<10; i++)
		printf("[%d]=%d\n", i, c[i]);
}
[/quote]

>>参考にしてみます[/quote]

non
記事: 1097
登録日時: 14年前

Re: マージと基数変換について

#29

投稿記事 by non » 14年前

>関数中にc[]が入っててもいいのでしょうか?

いいと思いますよ。

void marge(int a[],int b[],int c[]);
non

リヴァイアサン

Re: マージと基数変換について

#30

投稿記事 by リヴァイアサン » 14年前

いいと思いますよ。
>>PCが壊れてしまって確かめれなくなってしまったので別のPCで今の意見を聞いて憶測でプログラム書きますが

コード:

 
#include <stdio.h>
 
int merge(int a[], int b[], int c, int m){ 
    int i,ia,ib,ic;
    ia=ib=ic=0;
    while(ic<10){
        if(ia<5 && ib<5){
            if(a[ia]<b[ib])
                c[ic++]=a[ia++];
            else
                c[ic++]=b[ib++];
        }
        else if(ia==5)
            c[ic++]=b[ib++];
        else
            c[ic++]=a[ia++];
    }
 }

main(){
 int x[]={1,2,3,4,5}, y[]={1,2,3,4,5}, i, z[10];
    for(i=0; i<10; i++)
        printf("[%d]=%d\n", i, merge(x, y, z, 5));
}
こんな感じでしょうか?

リヴァイアサン

Re: マージと基数変換について

#31

投稿記事 by リヴァイアサン » 14年前

こうでした

コード:

 
#include <stdio.h>
 
int merge(int a[], int b[], int c[], int m){ 
    int i,ia,ib,ic;
    ia=ib=ic=0;
    while(ic<10){
        if(ia<m && ib<m){
            if(a[ia]<b[ib])
                c[ic++]=a[ia++];
            else
                c[ic++]=b[ib++];
        }
        else if(ia==m)
            c[ic++]=b[ib++];
        else
            c[ic++]=a[ia++];
    }
 }

main(){
 int x[]={1,2,3,4,5}, y[]={1,2,3,4,5}, i, z[10];
    for(i=0; i<10; i++)
        printf("[%d]=%d\n", i, merge(x, y, z, 5));
}

初級者
記事: 200
登録日時: 14年前

Re: マージと基数変換について

#32

投稿記事 by 初級者 » 14年前

merge() の最後の引数が有効に活用できていませんね。
5 や 10 といった固定値は、最後の引数を使った方がいいと思います。

リヴァイアサン

Re: マージと基数変換について

#33

投稿記事 by リヴァイアサン » 14年前

merge() の最後の引数が有効に活用できていませんね。
5 や 10 といった固定値は、最後の引数を使った方がいいと思います。

>>つまりこういうことでしょうか?

コード:

#include <stdio.h>
 
int merge(int a[], int b[], int c[], int m){ 
    int i,ia,ib,ic;
    ia=ib=ic=0;
    while(ic<2*m){
        if(ia<m && ib<m){
            if(a[ia]<b[ib])
                c[ic++]=a[ia++];
            else
                c[ic++]=b[ib++];
        }
        else if(ia==m)
            c[ic++]=b[ib++];
        else
            c[ic++]=a[ia++];
    }
 }
 
main(){
 int x[]={1,2,3,4,5}, y[]={1,2,3,4,5}, i, z[10];
    for(i=0; i<10; i++)
        printf("[%d]=%d\n", i, merge(x, y, z, 5));
}

初級者
記事: 200
登録日時: 14年前

Re: マージと基数変換について

#34

投稿記事 by 初級者 » 14年前

正しい結果が出ているのでしょうか。
merge() は戻り値の型が int ですが、何も戻していませんね。
その、何も戻していない値を main() で使えるのでしょうか。

リヴァイアサン

Re: マージと基数変換について

#35

投稿記事 by リヴァイアサン » 14年前

正しい結果が出ているのでしょうか。
merge() は戻り値の型が int ですが、何も戻していませんね。
その、何も戻していない値を main() で使えるのでしょうか。

>>すいません、上にも書いたのですが確認できるPCが壊れてしまったため憶測で書くことしかできないです

non
記事: 1097
登録日時: 14年前

Re: マージと基数変換について

#36

投稿記事 by non » 14年前

今作っている関数は、配列aと配列bの小さい方から配列cにすべてを格納するプログラムを作っています。
関数の目的が理解できているなら、それをforで10回も行うことにどんな意味があるのでしょうか?
non

リヴァイアサン

Re: マージと基数変換について

#37

投稿記事 by リヴァイアサン » 14年前

今作っている関数は、配列aと配列bの小さい方から配列cにすべてを格納するプログラムを作っています。
関数の目的が理解できているなら、それをforで10回も行うことにどんな意味があるのでしょうか?

>>今まで配列の要素数の数だけfor文を繰り返すものだと思ってたのでこういうふうにしたんですが

あとこの話題に関係ないですが関数中にreturn ●●みたいなのをつけちゃいけないですか?

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: マージと基数変換について

#38

投稿記事 by h2so5 » 14年前

リヴァイアサン さんが書きました: あとこの話題に関係ないですが関数中にreturn ●●みたいなのをつけちゃいけないですか?
戻り値の型がintなので、付けなければいけないんです。

non
記事: 1097
登録日時: 14年前

Re: マージと基数変換について

#39

投稿記事 by non » 14年前

>関数中にreturn ●●みたいなのをつけちゃいけないですか?

必要があるならreturn を行っていいです。
関数の仕様をしっかり検討してください。

ただ、今回のmergeの関数は int型の値を返す必要がありますか?
non

リヴァイアサン

Re: マージと基数変換について

#40

投稿記事 by リヴァイアサン » 14年前

戻り値の型がintなので、付けなければいけないんです。[/quote]
>>この場合リターンすべきものがなんなのかがわからないのですが、配列がそれにあたるのでしょうか?

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: マージと基数変換について

#41

投稿記事 by みけCAT » 14年前

リヴァイアサン さんが書きました:あとこの話題に関係ないですが関数中にreturn ●●みたいなのをつけちゃいけないですか?
どうしてこのように思われましたか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

リヴァイアサン

Re: マージと基数変換について

#42

投稿記事 by リヴァイアサン » 14年前

ただ、今回のmergeの関数は int型の値を返す必要がありますか?

>>しなければならないみたいなのですが… どっちなんでしょうか…?

リヴァイアサン

Re: マージと基数変換について

#43

投稿記事 by リヴァイアサン » 14年前

どうしてこのように思われましたか?

>>ただの勘です

初級者
記事: 200
登録日時: 14年前

Re: マージと基数変換について

#44

投稿記事 by 初級者 » 14年前

マネしてはいけないコードの例です。

コード:

#include <stdio.h>
#include <stdlib.h>

#define N (5)

int *merge(int *p, int *q, int n)
{
    int *r, ip, iq, ir;

    r = (int *) malloc(sizeof(int) * 2 * n);
    if (r == NULL)
        exit(1);
    for (ip = iq = ir = 0; ir < 2 * n; ir++) {
        if (ip < n && iq < n)
            r[ir] = (p[ip] <= q[iq]) ? p[ip++] : q[iq++];
        else
            r[ir] = (ip != n) ?        p[ip++] : q[iq++];
    }
    return r;
}

void print(int *p, int n)
{
    int i;

    for (i = 0; i < n; i++)
        printf("%d ", p[i]);
    putchar('\n');
}

int main(void)
{
    // 初期値は適当に決める
    int a[N] = { 10, 20, 30, 40, 50 }, b[N] = { 15, 18, 35, 45, 48 }, *c;
    
    printf("マージ前\n");
    print(a, N);
    print(b, N);
    c = merge(a, b, N);
    printf("\nマージ後\n");
    print(c, 2 * N);
    free(c);
    return 0;
}

non
記事: 1097
登録日時: 14年前

Re: マージと基数変換について

#45

投稿記事 by non » 14年前

リヴァイアサン さんが書きました:戻り値の型がintなので、付けなければいけないんです。
>>この場合リターンすべきものがなんなのかがわからないのですが、配列がそれにあたるのでしょうか?[/quote]

あなたが、int merge(int a[], int b[], int c[], int m) と書いたからです。

私は、
void marge(int a[],int b[],int c[])と前に書きましたが・・・

自分で必要があるから、私の提案を無視して、別のプロトタイプにしたのでしょ。
non

リヴァイアサン

Re: マージと基数変換について

#46

投稿記事 by リヴァイアサン » 14年前

あなたが、int merge(int a[], int b[], int c[], int m) と書いたからです。

私は、
void marge(int a[],int b[],int c[])と前に書きましたが・・・

自分で必要があるから、私の提案を無視して、別のプロトタイプにしたのでしょ。

>>全然気づいてませんでしたすいません
せっかく提案していただきましたのでvoidの方でこの先進めてもらってもいいでしょうか?

初級者
記事: 200
登録日時: 14年前

Re: マージと基数変換について

#47

投稿記事 by 初級者 » 14年前

せっかくquoteというタグがあるのですから、
使ってほしいです。

ご自分の発言と他人の発言が区別しにくくなっています。

リヴァイアサン

Re: マージと基数変換について

#48

投稿記事 by リヴァイアサン » 14年前

初級者 さんが書きました:せっかくquoteというタグがあるのですから、
使ってほしいです。

ご自分の発言と他人の発言が区別しにくくなっています。
>>すいません気をつけます

リヴァイアサン

Re: マージと基数変換について

#49

投稿記事 by リヴァイアサン » 14年前

これで多分いいと思うのですが

コード:

#include <stdio.h>
 
void merge(int a[], int b[], int c[]){ 
    int i, ia, ib, ic;
    ia=ib=ic=0;
    while(ic<10){
        if(ia<5 && ib<5){
            if(a[ia]<b[ib])
                c[ic++]=a[ia++];
            else
                c[ic++]=b[ib++];
        }
        else if(ia==5)
            c[ic++]=b[ib++];
        else
            c[ic++]=a[ia++];
    }
 }
 
main(void){
 int x[5]={1,2,3,4,5}, y[5]={1,2,3,4,5}, i, z[10];
 merge(x,y,z);
    for(i=0; i<10; i++)
      printf("[%d]=%d\n", i, z[i]);
}

non
記事: 1097
登録日時: 14年前

Re: マージと基数変換について

#50

投稿記事 by non » 14年前

関数merge では i は使っていません。

mainは int main(void) にしましょう。
したがって、main関数の最後に return 0; を付け加えます。
non

リヴァイアサン

Re: マージと基数変換について

#51

投稿記事 by リヴァイアサン » 14年前

non さんが書きました:関数merge では i は使っていません。

mainは int main(void) にしましょう。
したがって、main関数の最後に return 0; を付け加えます。
>>わかりました。
とりあえずこれで一段落つけたみたいなので寝ることができそうです
基数関数の方は精神的身体的につらくなったので断念します
長い時間ありがとうございました

かずま

Re: マージと基数変換について

#52

投稿記事 by かずま » 14年前

リヴァイアサン さんが書きました: これで多分いいと思うのですが
最初の問題に「要素数5個の配列を2個用意する。別に要素数10個の配列を用意して」とあるので、それで良いと思います。
しかし、せっかく関数として処理を独立させるのだから、要素数を任意に指定できるようにしたほうが良いようにも思います。

コード:

#include <stdio.h>

int merge(int *a, int na, int *b, int nb, int *c, int nc)
{
    int ia = 0, ib = 0, ic = 0;
    if (nc < na + nb) return -1;
    while (ia < na && ib < nb)
        c[ic++] = (a[ia] < b[ib]) ? a[ia++] : b[ib++];
    while (ia < na) c[ic++] = a[ia++];
    while (ib < nb) c[ic++] = b[ib++];
    return ic;
}

#define SIZE(a) (sizeof(a) / sizeof(a[0]))
 
int main(void)
{
    int a[] = { 10, 20, 30, 40, 50 };
    int b[] = { 11, 20, 22, 25, 33, 64, 70 };
    int c[SIZE(a) + SIZE(b)], i, n;

    n = merge(a, SIZE(a), b, SIZE(b), c, SIZE(c)); 
    for (i = 0; i < n; i++) printf("[%d] = %d\n", i, c[i]);
    return 0;
}

閉鎖

“C言語何でも質問掲示板” へ戻る