• ベストアンサー

二つのint型配列を一つにするには?

2種類のint型配列にそれぞれ数が重ならないように数字を代入して行きます。この2種類のプログラムの違いは値を代入する方法以外はすべて同じです。ですから、ユーザー関数で一つにまとめようと考えてます。 2種類の違い:値を代入する方法がが違う。 (1)scanf()関数で人間が値を各要素に代入する。 (2)rand()関数でPC側が値を各要素に代入する。 配列への代入のルール (1)同じ値の場合は代入しなおさなければならない。 基本的には 人間側が値を要素に代入する場合 for( i = 0 ; i < 6 ; i++){ while(1){ scanf("%d",&dut[i]); for (j = 0; j < i ; j++){ if(dut[i] == dut[j]){flg = 1; break;} } if (flg == 0){break;} } } PC側がrand()関数を使い各要素に入力した場合 for( i = 0 ; i < 6 ; i++){ while(1){ pc[i] = rand()%43 + 1; for (j = 0; j < i ; j++){ if(pc[i] == pc[j]){flg = 1; break;} } if (flg == 0){break;} } } 以上の二つの違うところは「rand()関数かscanf()」どちらかが入るだけです。あとはみな同じつづりなのです。だから一つに出来ると思うのです。 共有して使える関数はどんどんまとめちゃうのが私の考えですので。 ※ヘッダ呼び出しや、変数定義など基本的な部分は省いてあります。 間違いがあるときはおしえてください。 ※また、別の方法があるときはぜひおしえてください。

  • nVIDIA
  • お礼率46% (520/1121)

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

  • ベストアンサー
  • rentahero
  • ベストアンサー率53% (182/342)
回答No.6

> タイトル考えたらおかしい。質問するのにがてなのですというか、 > こわいですね。この人おかしいのではないかとか思われがちで。 > こちら側にも時間に余裕があればもうすこし冷静に質も > 出来たのですが… いや、べつに「おかしい」なんて思いませんけど。今回の場合、明らかに違うもの(関数の統合と配列のマージ)を想像してしまったので、その点を書いてみたんです。 それより、いったいなんでそんなに時間に余裕がないのかそのほうが気になりますね。 まあその辺は深くつっこまないでおくとして どちらかというと、このような疑問が出てくることが重要なのであって、やっつけ仕事でクズコードを量産しても初心者一歩先から先へは進めません。 そういう意味では、この質問はそれはそれでいいと思います。タイトルが謎なだけで、質問自体は問題点もやりたいこともはっきりしているので、良問の類になると思います。 プログラムのテクニックはお絵かきや文章と同じでとにかく上達するには、まず量をこなすこと、慣れたら次に習得したいテクニックを意識してさらに量をこなすことです。がんばってね。 せっかくなので、参考URLに上達するのによいページを挙げておきます。キツイですよ?ひどいコードがたくさん出てきますから(ひどいコードを診断するという趣旨のページですから、当然なのですけど)

参考URL:
http://www.pro.or.jp/~fuji/mybooks/cdiag/
nVIDIA
質問者

お礼

課題の作成真っ最中でしたので、あれこれ考えていて、自分でもって優れたものを作りたい。もっと上達したい。せっかくサーティファイの検定合格したから最上階まで行きたいなどなど、人間の欲望丸出しだったので、混乱したのかもしれません。 アルゴリズムって冷静に考えるべきなのですが、性格があわてんぼうなので…。 応援ありがとうございます。

その他の回答 (6)

  • sha-girl
  • ベストアンサー率52% (430/816)
回答No.7

// 変数定義等は略 void func(int num , int* pc) { for( i = 0 ; i < 6 ; i++){ while(1){ pc[i] = num; for (j = 0; j < i ; j++){ if(pc[i] == pc[j]){flg = 1; break;} } if (flg == 0){break;} } } } PC側のとき func( rend()%43 + 1 , pc ); 人間側のとき int num; scanf("%d",num); func(num,pc); 分けるとしたらこんな感じですかね。

noname#168973
noname#168973
回答No.5

ご質問の仕様をみて、私ならまず foo(dut, ...) {  do {   入力(dut, ...);  } while (同一?(dut, ...)) } と思いつきました。foo(dut, ...) が纏めた(目的の)関数ですね。 で、後は「入力(dut, ...)」と「同一?(dut, ...)」の実装を考える訳ですが、「同一?(dut, ...)」の方は今回の場合、固定だと思うので、上記 foo() 関数の外に、別途定義すれば良いと思います(詳しくは記述しませんが、内容は簡単に想像できますよね)。 残るは、「入力(dut, ...)」をどうするかですが、これは他の方も記述されているように、色々な方法があると思います。 C で書くなら、私も call-back (関数のポインタ)、C++ なら、object を foo() の引数に渡すことになるでしょうか。 なお、もしも C++ でいいなら「同一?(dut, ...)」も、わざわざ自分でコード書かなくても std::map なんかで代用できそうです。 ## 更に C++ なら、ご質問に記述のコードをそのまま、 ## template にするってのは反則でしょうか?? ^^)

回答No.4

No. 3 です。 「おすすめします」だけではなんなので、ちょっとした例を。 こういう雰囲気で記述することが出来ます。 あと、下記の URL には、ずっと以前に、同じようにカードゲームを題材にしたC++の話を挙げています。 ちょっと、C++ の文法が古いですが、気持ちはわかるかもというところでしょう。 class player { protected: int card[6]; virtual int getCard() = 0; public: void init() { while(カーが揃わない) { value = getCad(); // ここで、配列への代入処理 } } }; class person : public player { int getCard() { int i; cin >> i; return i; } } class commputer : public plyaer { int getCard() { return rand() % 42 + 1; } };

参考URL:
http://www.asahi-net.or.jp/~ig5k-fjhr/tec/cpp1.htm
nVIDIA
質問者

お礼

参考にさせていただきますありがとうございました。

回答No.3

一般的に言って、「同じ綴りだからまとめる」というのは、それだけではあまり良い方針とは言えません。 もっと、理論的な動作や全体の構造をふまえた上でないと。 そういう意味で、この場合なら、C++ のクラスを理解することをおすすめします。 同じ綴りだから……ではなく、「入力方法が違うだけで、それ以外の処理は同じ」というのを、文字通りにプログラムすることが出来ます。

nVIDIA
質問者

お礼

ただ同じ部分があるから共有すればよいというわけではないのですね。わかりました。どうもありがとうございます。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

2種類の処理を関数にまとめる方法を教えて欲しいということでよろしいでしょうか?そう解釈して回答します。 void func(int array[], void (*f)(int*)) {  for( i = 0 ; i < 6 ; i++){   while(1){    (*f)(&array[i])    for (j = 0; j < i ; j++){     if(array[i] == array[j]){flg = 1; break;}    }    if (flg == 0){break;}   }  } } こんな感じでどうでしょうか。

  • rentahero
  • ベストアンサー率53% (182/342)
回答No.1

あの~前の質問も見てましたけど、ちゃんと理解してますか? まとめるのはいいのですが、違いの部分をまとめる部分の外に出さないとまとめにくいですよ。 もちろんこのままでも何とかして外に出せばできるのですが… このままのロジックで何とかして外に出す方法としては、 (1)一番外のfor文についてはあきらめて、まとめる部分を「(1)同じ値の場合は代入しなおさなければならない。」だけにする (2)代入を専用の関数にして、入力先をさらにenumや#defineマクロで外から指示する (3)代入を専用の関数にして、その関数ポインタを外から渡して、関数内からコールバックする などが考えられます。 私なら、グダグダ言う前に全面的に書き直してしまいますが、どうしてもこのロジックでやらなければならないのであれば、さらに別の方法(ディスクから読み取る、ネットワークから受け取る、など)がでてくるのがミエミエなので、(2)にするかな。関数ポインタでやると後で他人が読めなくなっちゃいそうだし。 あと、二つのint配列をひとつにする、という質問からは、配列をマージすることが浮かびました。タイトルを適切につけるのも大事だと思います。

nVIDIA
質問者

補足

タイトル考えたらおかしい。質問するのにがてなのですというか、こわいですね。この人おかしいのではないかとか思われがちで。こちら側にも時間に余裕があればもうすこし冷静に質も出来たのですが…

関連するQ&A

  • 非常にはずかしい質問ですが 配列の質問です。

    C言語の勉強で時間が経つごとに、肝心の基礎が忘れがちになるのですよね。 それに、配列に対しての説明ってほとんど文字列ばかりで整数はみつからないです。 今回の質問は ・int型配列の要素ひとつずつ代入するにはどうするか? ・同じ数字を代入させないにはどうするか? ・配列中n個の要素を表示させるにはどうするのか? 条件 1、配列の要素はn個 2、同じ数は× 一応かいてみました。 { int buffer[6], i, j, signal ; srand((unsigned int)time(NULL)); for( i = 0 ; i < 6 ; i++){ buffer[i] = rand()%42+1; for( signal = 0 , j = 0 ; j < i ; j++ ){ if(buffer[i] == buffer[j]){signal = 1; break;} } if(signal == 0){break;} } printf("%d\n",buffer);

  • 配列のポインタについて

    C言語で処理が下記のような処理を作成したいと思っております。 関数の引数によって、データを代入する配列を切り替えたいと考えております。 下記のような処理を考えた場合、if文の中・for文のbuffをどのように処理すれば よいでしょうか? アドバイスよろしくお願い致します。 int a[100][150]; int b[100][150]; void sample(int flg) { int i,j; unsigned short *buff; if(flg == 0){ buff = &a; }else{ buff = &b; } for( j=0 ; j<100 ; j++ ){ for( i=0 ; i<150 ; i++ ){ buff[y][x] = data; x++; } x = 0; y++; } }

  • PHPで素数を表現に関するご質問

    PHPで素数を表現する際に関しての質問です。 ■知りたい点 下記のコードで、iが3の時、 for($j =3; $j < $i; $j++){ の $j < $i の動作の仕方がわかりません。 3 < 3 だから、条件に反する。よって処理なし? とか考えてしまっています。 どのような、解法をしているのでしょうか。 お手数をお掛けしますが、よろしくお願い致します。 P.S すみません。質問があいまいで答えずらいかと思います。。。 <?php //関数の呼び出し sosuu_check(); //素数を表示する関数 function sosuu_check() { //1~100までを繰り返す for($i=1;$i<=100;$i++) { //1以下の場合は次の値をチェックする if($i < 2) { continue; } //2の場合は素数なので表示して、次の値をチェックする。 if($i == 2) { print $i . ":"; continue; } //偶数の場合は素数ではないので、次の値をチェックする。 if($i % 2 == 0) { continue; } $flg = "0";//割り切れたか判定するフラグ変数 //今の値は1と今の値以外では割れてはいけない。 for($j = 3;$j < $i; $j++){ //割れてしまったら素数ではないので次の値をチェックする。 if($i % $j == 0){$flg = "1";break;} } //割れなかった場合は素数なので表示する。 if($flg == "0") { print $i . ":"; } } } ?>

    • ベストアンサー
    • PHP
  • 配列 隣の要素を参照するのですが

    最初に 8つの要素を持つint型の配列(配列名dat)があるとして、最初全要素に「0」が代入されています。scanf関数でn番の要素に「1」が代入されたとします。n番なのでどこに「1」が代入されたかはわからないです。 問題 for文を使用して何番目に「1」が入力されたかを調べますが、以下のルールに従がわなくてなならいです。 ルール ・現在の要素から隣の要素を参照しなくてはいけない。 ・参照する範囲は要素の数「0~7」番 #include<stdio.h> void main() { int i, dat[8]; for(i=0;i<8;i++){ dat[i]=0; } i=0; scanf("%d",&i); dat[i] = 1; for(i=0;i<8;i++){ if(dat[i+1] == 1){print("%d列目に「1」がありました", i+1); } } でも…こうすると0番目の要素が参照されないですそれを回避するには?そして… 最大の要素(dat[7])にきたときは隣を参照しないようにするにはどうすればよいのでしょう?

  • 二次元配列とポインタについてよくわかりません

    二次元配列の要素を代入しようと思って double *pa; for(i = 0; i < 4; i++){ for(j = 0; j < 4; j++){ printf("A[%d,%d]=", i + 1, j + 1 ); scanf("%lf", pa + i + j); printf("A[%d,%d]=%g\n", i + 1, j + 1, *(*(pa + i) + j) );}} とやっているのですがどうやらscanfで上手くいかず最後のprintfが表示されません あと double (*pb)[4]; printf("4 x 4 行列 Bの要素を入力してください>\n"); for(i = 0; i < 4; i++){ for(j = 0; j < 4; j++){ printf("B[%d,%d]=", i + 1, j + 1 ); scanf("%lf", &pb[i][j]);}} もうまくいきません (二通りの方法でしなければ成らないので) どうしたらいいでしょうか?

  • ポインタと {   } の関係とは

    戻り値が配列(ポインタ)で返す関数を二つ作りif文で選択できるようにしたら 各要素の値がうまく表示されません。 最初に配列の各要素に自分で値を代入するか、ランダムに値を代入させるか決めて、代入させた配列を最後に表示させたいわけです。 #include <stdio.h> int RegistData(int *); int RandomData(int *, int); void main(){ int mous[6]; int select; printf("自分で表示入力するときは1を、コンピュータに任せるときは0を入力してください。"); scanf(" %d", &select); if(select == 0){  *mous = RandomData(mous); }else if(select == 1){ *mous = RegistData(mous); } for( i = 0 ; i < 6 ; i++) printf("%d ", mous[i]); } printf("\n"); } RandomData(int *mous) { //rand()関数でランダムに各要素に値を代入する処理をします。 return *mous; } RegistData(int *mous) { //自分で要素に値を代入する処理をします。 return *mous; } ちなみに、あらかじめ要素に値を入れておくと正常にうごきます。 int mous[6] = { 10, 15, 12, 23, 33, 42};//動作確認用表示

  • 先頭0で重複のない配列を作りたい

    重複なく4つの領域を持つ配列に数字を代入したい(先頭は0以外の 数字)と思って書いたプログラムです。 しかし、コンパイルしてみると重複が発生してしまいます。 これはなぜ発生してしまうのでしょうか? よろしくお願いします。 #include<stdio.h> #include<stdlib.h> #include<time.h> int main(void) { int num,val,i,j; int comp[4]; srand(time(NULL)); puts("4桁の数字を記憶して逆向きに入力しましょう。"); val=rand()%10; do{ comp[0]=val; }while(comp[0]==0); for(i=1;i<4;i++) { do{ val=rand()%10; for(j=0;j<i;j++) { if(comp[j]==val) { break; } } }while(i<j); comp[i]=val; } for(i=0;i<4;i++) { printf("%d",comp[i]); } return 0; }

  • 一度に複数の値を取得できる乱数ってありますか?

    PHP Version 5.1.6を使っています。 例えば、1から10まで整数の中から値が重複しないように ランダムに8個選びたいような時で、自分が思いつた選び方は、 for($i=0; $i<8; $i++){ $r = rand(1, 10); $flag = false; for($j=0; $j<Count($list); $j++){ if($r == $list[$j]){ $flag = true; break; } } if($flag){ $i--; continue; } $list[] = $r; } print_r($list); なんですが、これだと効率が悪いような気がします・・・ そこで重複しないようにランダムに選べる乱数や またはそういう関数はあるのでしょうか?

    • 締切済み
    • PHP
  • できているとは、思うのですが。ポインタの配列を

    コンパイラではちゃんと動いてます。 1 2 3 0 1 2 3 という具合です。 気になるのは、printarrayの部分が正しいのか、ちょっと悩んでいます 問題としては main関数では0の値を読み込むまで最大99(MAX-1)個の値を配列 xに読み込んでいる。引数のポインタからの値を、値が0になるまで すべて1行に1つづつ画面に出力する関数printarray()を作成し、 プログラムを完成せよ。 引数はアドレスとして受け取る事。(配列としてでなく) フォーマットは、 "%d¥n" とする。(余計な出力はしない事。) (0は出力しない。) main内部を変更してはならない。 以下がソースです。 ご指摘よろしくお願いします。 #include <stdio.h> #define MAX 5 void printarray(int *); int main() { int x[MAX], i; int *p; x[MAX-1] = 0; for (i = 0, p = x; i < MAX-1; ++i, ++p) { scanf("%d", p); if (*p == 0) { break; } } printarray(x); return 0; } void printarray(int *a) { int i,*p; for(i = 0, p = a; i < MAX-1; ++i,++p) { if(*p == 0){ // continue; break; }else{ printf("%d\n", *(a+i)); } } }

  • 要素数が10の配列で、乱数0~9の値が重複しないようにする方法がわからなくて困っています。

    JAVAの練習問題でわからなくて困っています 以下は線形探索のプログラムで、このプログラムを改良して、 要素数が10の配列で、乱数0~9の値が重複しないようにする方法がわからなくて困っています。 以下のような簡単なプログラムでできる方法で行いたいです。 どなたか答えまたはヒントを下さい、お願いします。 ------------------------------------------------------------ import java.util.Random; import java.util.Scanner; public static void main (String[] args) { Random rand = new Random(); Scanner stdIn = new Scanner(System.in); final int n = 10; //要素数 int[] a = new int[n]; //配列を宣言 for (int j = 0; j < n;) a[j] = rand.nextInt(10); System.out.print("配列aの全要素の値\n{ "); for (int j = 0; j < n; j++) System.out.print(a[j] + " "); System.out.println("}"); System.out.print("探す数値 : "); int key = stdIn.nextInt(); int i; for (i = 0; i < n; i++) if (a[i] == key) break; if (i < n) //探索成功 System.out.println("それはa[" + i + "]にあります。"); else //探索失敗 System.out.println("それはありません。"); } }

専門家に質問してみよう