• ベストアンサー

線形探索について

C言語の線形探索の課題なんですが 5つの整数を入力して その入力した値からみつけたい値を探索する課題なのですが #include <stdio.h> /*--- 要素数nの配列aからkeyと一致する要素を線形探索 ---*/ int search(const int a[], int n, int key) { int i = 0; while (1) { if (i == n) return (-1); /* 探索失敗 */ if (a[i] == key) return (i); /* 探索成功 */ i++; } } int main(void) { int i, ky, idx; int x[4]; int nx = sizeof(x) / sizeof(x[0]); printf("%d個の整数を入力してください。\n", nx); for (i = 0; i < nx; i++) { printf("x[%d]:", i); scanf("%d", &x[i]); } printf("探す値:"); scanf("%d", &ky); idx = search(x, nx, ky); /* 配列xから値がkyである要素を線形探索 */ if (idx == -1) puts("探索に失敗しました。"); else printf("%dは%d番目にあります。\n", ky, idx + 1); return (0); } ここまではわかるのですが、 x[0]=99 x[1]=99 x[2]=88 x[3]=99 x[4]=22 と入力したときに 99は 1番目に見つかりました 2番目に見つかりました 4番目に見つかりました と出力したいのですがうまくいきません 線形探索で同じ数値を探索するにはどうすればよいのですか?

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

  • ベストアンサー
  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.1

#include <stdio.h> /*--- 要素数nの配列aからkeyと一致する要素を線形探索 ---*/ int search(const int a[], int n, int key) { int i = 0; while (1) { if (i == n) return (-1); /* 探索失敗 */ if (a[i] == key) return (i); /* 探索成功 */ i++; } } int main(void) { int i, ky, idx, t, f; int x[5]; int nx = sizeof(x) / sizeof(x[0]); printf("%d個の整数を入力してください。\n", nx); for (i = 0; i < nx; i++) { printf("x[%d]:", i); scanf("%d", &x[i]); } printf("探す値:"); scanf("%d", &ky); t = 0; f = -1; while (t < nx) { idx = search(&x[t], nx - t, ky); /* 配列xから値がkyである要素を線形探索 */ if (idx != -1) { idx += t; printf("%dは%d番目にあります。\n", ky, idx + 1); t = idx + 1; f = 0; } else break; } if (f) puts("探索に失敗しました。"); return (0); }

その他の回答 (2)

回答No.3

#include <stdio.h> int search(const int a[], int n, int key) { int i = 0; while(1){ if (i == n) return (-1); if (a[i] == key) return (i); i++; } } int main(void) { int i, ky, idx; int x[4]; int nx = sizeof(x) / sizeof(x[0]); printf("%d個の整数を入力してください。\n", nx); for (i = 0; i < nx; i++){ printf("x[%d]:", i); scanf("%d", &x[i]); } printf("探す値:"); scanf("%d", &ky); for(i = 0; i < 4 && (idx = search(&x[i], nx, ky)) != -1; ){ i += idx + 1; printf("%dは%d番目にあります。\n", ky, i); nx -= idx + 1; } if (i == 0) puts("探索に失敗しました。"); return (0); }

回答No.2

#include <stdio.h> typedef void (*callback)(int, void*); /*--- 要素数nの配列aからkeyと一致する要素を線形探索 ---*/ void search(const int a[], int n, int key, callback cb, void* arg) {   int i;   for ( i = 0; i < n; ++i ) {    if (a[i] == key) (*cb)(i, arg);   } } void found(int n, void* arg) {   printf("%dは%d番目にあります。\n", *(int*)arg, n + 1); } int main() {   int x[] = { 99,99,88,99,22 };   int target = 99;   search(x, 5, target, &found, &target);   return 0; }

関連するQ&A

  • このプログラムの説明合っていますか?

    /* 線形探索(for文で実現)*/ #include <stdio.h> /*--- 要素数nの配列aからkeyと一致する要素を線形探索 ---*/ int search(const int a[], int n, int key)    { int i;            /*iを宣言*/ for (i = 0; i < n; i++)     /*iの値を設定し宣言*/ if (a[i] == key)       /*iにkeyで入力*/ return (i); /* 探索成功 */ return (-1); /* 探索失敗 */ } int main(void)          /*main関数*/ { int i, ky, idx;/*i,ky,idxを宣言*/ int x[7]; /*xは配列で7つの数字を入れられる*/ int nx = sizeof(x) / sizeof(x[0]);/*配列を宣言*/ printf("%d個の整数を入力してください。\n", nx); for (i = 0; i < nx; i++) { printf("x[%d]:", i); scanf("%d", &x[i]); }printf("探す値:"); scanf("%d", &ky); idx = search(x, nx, ky); /* 配列xから値がkyである要素を線形探索 */ if (idx == -1) puts("探索に失敗しました。"); else printf("%dは%d番目にあります。\n", ky, idx + 1); return (0);      /*0の数字で戻る*/ } 1行ずつ理解したいのですが分からない個所多いんです。 分からないの文は説明が書いてないので教えてください。

  • 線形探索と二分探索

    線形探索と二分探索のプログラムを作成中です。 自力(本やwebに落ちているサンプルを参考にして)でここまで作りましたが正直自信がありません。どうかお願いします。 #include <stdio.h> #define ARRAYI1_MAX sizeof(array1) #define ARRAYI2_MAX sizeof(array2) //int binary_search(int*,int,int); //二分探索関数のプロトタイプ宣言 int liner_search(int*,int,int); //線形探索関数のプロトタイプ宣言 void main(void) { int array1[]={2,3,5,8,12,20,32,52}; int array2[]={22,34,65,66,12,33,43,5,1}; int result,key; printf("探す文字を入力して下さい。\n"); sacnf("%d",&key); result=liner_search(array1,ARRAYI1_MAX,key); if(result<0){ printf("見つかりませんでした\n");} else{ printf("%d番目に見つかりました\n",result);} } //線形探索 int liner_search(int*array,int num_array,int key) { int i=0; for(i=0;i<result;i++) } /*二分探索 int binary_search(int*array,int num_array,int key) { }*/

  • このプログラムどこがおかしいですか?

    コンパイルはできますが実行できません… どこがおかしいか分かる人教えてください。 このプログラムはファイルから名前 数学の点数、英語の点数を読み込んで文字データに入れた後構造体に入れて探し出す値の項目(キー)を入力して(何番目にあるか)探し出すというプログラムです。 #include <stdio.h> #include <string.h> #define NUMBER 10 //構造体を宣言する struct student { //名前、身長、体重を構造体オブジェクトのメンバに格納する関数の定義 char name[10]; char math[4]; char eng[4]; }; /*--- 要素数nの配列aからkeyと一致する要素を線形探索(番兵法) ---*/ int search(struct student *b, int n, char key) { int i=0; b[i].name[0]=key; // 番兵を追加 while (1) { if (b[i].name[0] == key) break; /* 見つけた */ i++; } return (i == n ? -1 : i); } int main(void) { FILE *fpin; struct student a[NUMBER]; int i=0, idx,ret; char buffer[20],ky; int nx=sizeof(buffer) / sizeof(buffer[0]); fpin=fopen("input2.txt","r"); //テキストファイルを読み取りモードで開く while(fgets(&buffer[0],sizeof(buffer),fpin) !=NULL ) { if(i>=100) break;//読み込む人数が100人を超えてる時の処理 ret=sscanf(&buffer[0],"%s %s %s",&a[i].name,&a[i].math,&a[i].eng); //データ文字列を3分割 if(ret!=3) //3に分割できなかったときの処理 { puts("代入された入力項目の個数が3でありません"); goto END; } printf("%s %s %s\n",&a[i].name,&a[i].math,&a[i].eng); i++; } printf("探す値:"); scanf("%s", &ky); idx = search(a, nx - 1, ky); /* 配列xから値がkyである要素を線形探索 */ if (idx == -1) puts("探索に失敗しました。"); else printf("%dは%d番目にあります。\n", ky, idx + 1); END: fclose(fpin); return 0; }

  • 線形探索(番兵法)のプログラムについて。

    線形探索(番兵法)のプログラムについて考えています。 メイン関数からsearch関数に値を渡してそこで探索させるのですが、 int search(int a[], int n, int key) { int i = 0; a[n] = key; while (1) { if (a[i] == key) break; i++; } return (i == n ? -1 : i); } のwhileを使ったやり方からfor文を使ったやり方に変更したいと思っています。 色々な方法でプログラムを考えてみたいので。 そうすると、なんかうまくいきません。 for文だとどのように考えたらいいのでしょうか?

  • 線形探索

    c++で線形探索をするプログラムを教えてください。 キーボードから入力した数字の中からある値があるかどうか調べるものです。

  • 線形探索法のプログラムについて

    配列Aに格納されている数字を検索するプログラムより、 Aのプログラムでは配列Aに格納されている数字を検索(scanf("%d" , j)で入力)した にもかかわらず、「該当するデータがありませんでした」と表示されてしまいます。 Bのプログラムでは、配列Bに格納されている数字を検索(scanf("%d" , j)で入力)すると 「該当するデータがありました」と表示されます。 Aのプログラムで、------でかこってある部分に問題があると思われ、 いろいろと試してみましたが、未だにその理由をつかむことができません。 その理由を知りたく、書き込みを致しました。 ご教授の程宜しくお願い致します。 A. main(){ int i , j; int k = 0; int A[5] = {4 , 1 , 3 , 4 , 5}; printf("検索する数値を入力してください > "); scanf("%d" , j); --------------------------------------------------------------- for(i=0 ; i<5 ; i++){ if(A[i] == j){ printf("該当するデータはあります"); k++; } } --------------------------------------------------------------- if(k <= 0){ printf("該当するデータがありませんでした\n"); } return; } B #include<stdio.h> main(){ int i , j , k; int A[5] = {4 , 1 , 3 , 4 , 5}; printf("検索する数値を入力してください > "); scanf("%d" , j); for(i=0 ; i<5 ; i++){ if(A[i] == j){ k++; } } if(k>0){ printf("該当するデータはありました"); }else{ printf("該当するデータはありませんでした"); } return; }

  • 線形探索のエラーがでて困っています

    線形探索を用いて表を作るプログラムを作ったのですが、データの数が10000ならば作動するのですが、それ以上になってしまうとセグメントエラーが起こります。なぜだが教えていただけないでしょうか? #include <stdio.h> #include <stdlib.h> #include <time.h> #define N 1000000 #define M 10 typedef int Key; typedef struct item{ Key key; }Item; struct table { int n; Item item[N]; }; typedef struct table *Table; Item *lookup_item(Table table ,Key key){ int i=0; while(1){ if(i==table->n) return (0); if(table->item[i].key==key) return &(table->item[i]); i++; } return 0; } int add_item(Table table, Item item){ int i; int n=table->n; if(lookup_item(table ,item.key)!=0) return (0); else { table->item[n].key=item.key; table->n++; return (1); } } Table new_table(){ Table table; table = (Table)malloc(sizeof(table)); return table; } int remove_item(Table table, Key key){ int i=0; int n=table->n; if(lookup_item(table,key)!=0) { while(1){ if(table->item[i].key==key){ table->item[i].key=table->item[n-1].key; table->n--; return 1; } i++; } } else return (0); } Key keys[N]; int main() { Table table; Item item; clock_t t1, t2; char buff[128]; int i, j, n; /* ファイルからキーを読み込み keys[] に格納する。*/ for (n=0; n<N && fgets(buff, 128, stdin)!=NULL; n++) { keys[n] = atoi(buff); } /* 表を用意する。*/ table = new_table(); /* 追加項目数と全項目の追加に必要な時間(秒単位)を印字する。*/ t1 = clock(); for (i=j=0; i<n; i++) { item.key = keys[i]; j += add_item(table, item); } t2 = clock(); printf("%d %.3f\n", j, (double)(t2-t1)/CLOCKS_PER_SEC); /* 探索成功数と全項目の探索に必要な時間(秒単位)を印字する。*/ t1 = clock(); for (i=j=0; i<n; i++) { if (lookup_item(table, keys[i])!=NULL) j++; } t2 = clock(); printf("%d %.3f\n", j, (double)(t2-t1)/CLOCKS_PER_SEC); /* 削除項目数と全項目の削除に必要な時間(秒単位)を印字する。*/ t1 = clock(); for (i=j=0; i<n; i++) { j += remove_item(table, keys[i]); } t2 = clock(); printf("%d %.3f\n", j, (double)(t2-t1)/CLOCKS_PER_SEC); return 0; } よろしくお願いします。

  • C言語の基礎 . 2乗値の差について

    ---------------------------------------------------------------- /*二つの整数の二乗の差を求める*/ #include<stdio.h> /*二乗値を返す*/ int sqr(int x) { return (x*x); } /*--------差を返す-------*/ int diff(int x, int y) { return (x>y? x-y : y-x); } int main(void) { int kx,ky,kx2,ky2; printf("二つの整数を入力してください"); printf("整数kx:"); scanf("%d", &kx); printf("整数ky:"); scanf("%d", &ky); kx2 =sqr(kx); /* kxの二乗*/ ky2 =sqr(ky); /*kyの二乗*/ printf("kxの二乗とkyの二乗の差は%dです。\n", diff(kx2,ky2)); return 0; } 教えてください! 上のプログラミングの部分的にわからないです。 (1)最初の int sqr(int x)というのはどういう風に読めばいいのでしょうか? sqrというのはintのようにきめられた語ですか??? あとどうしてカッコの中にint xというのが入ってるのでしょうか。 今まではint iとか int noとかしてあったのですが、急に難しくなりました >_< (2)そのあと、{}の中は return (x*x)となっています。 これはxかけるxだと思いますが、良く分かってません。 コンパイルして実行した後は、プログラムを上から読むと習ったのですが、 そうすると意味はどうなるのでしょうか? (3)ここは多分重要なんだと思います int diff(int x,int y) return (x>y ? x-y : y-x); ここも多分条件だと思います。もしxがyより大きければ、 そのあとの?の意味を教えてください。 あとx-y:y-xの間の:意味はなんでしょうか?? どうしても今まで単純にfor(i=2;i<no;i++)という単純な式だったのですが 関数の項目になった途端に難しくなりました。。上はiは二からスタートで noまで行い、iの値は一つずつ増加していくです。 (4) in main (void)の下の分は大体OKです。(scanf)まで。 Kx2=sqr(kx); ky2=sqr(ky);とありますが、int main(void)の中で int kx,ky,kx2,ky2と 4つの箱を作ったとイメージしてます。 その中で、整数kxの値を実行した際に数字を入力したとします。 たとえば10.そうした場合scanfの分が &kxとなってますので kxに読み込みにいけという命令文になると思います。 では10の値をkxにいれたとして、 なぜkx2=sqr(kx);なのでしょう? sqr(kx)ってなんですか? 一番最初に作成した int sqr(int x)の部分に関連してますか? 先ほど10と入力したものは"kx"の箱の中には入ってると思いますので kx2=sqr(10)とは多分ならないと思ったのですが。。。 ごめんなさい、良く分かってないです、ただ、関数を最初に作成して diff(kx2,ky2)で読み込みに行ってるようには何となく本を読んで 理解してるのですが、まだよくわかってません。 どなたか、このプログラムの読み方を教えてください、お願いします!

  • ヒープの探索の再帰

    A[N]を利用したヒープのプログラムを作りました。 A[i]の親は、A[(i-1)/2]であるヒープです。 (上に行くほど小さい整数を格納) そしていまある整列されたヒープのなかからキーボードから入力した値xを検索する関数findを、 x ←検索する値 A[]←ヒープソートされた配列 n ←格納されているA[]の最後の添え字 として、 int find(int x, int *A, int i, int n) { if(A[i]==x){ printf("*\n"); /* ここの作業が行われているかを確認 */ return 1; } if(i>n)return 0; if(A[i]>x){ return 0; } else if (A[i]<x){ i = 2*i + 1; find(x, A, i, n); i++; find(x, A, i, n); } return 0; } というものを作ってみました。汚いかもしれませんが、とりあえず今はこれでいっぱいいっぱいです。 それで、当然のごとくうまくいきませんでした。 /**/内に書いたように、入力したxがヒープ内にある場合は「*」が一応表示されるのですが、どうもfindは1を返してくれません。0を返してしまいます。見つけた後もまだ再帰をくりかえしえしているようです。 どこがいけないのでしょうか。

  • C言語 探索に関して

    C言語探索プログラムについて質問です。 #include <stdio.h> #define MAXSIZE 100 void swapData(int *x, int *y){ int tmp; tmp = *x; *x = *y; *y = tmp; } void simpleSort(int data[], int first, int last) { int i, j; for(i = first; i < last; i++){ for(j = i+1; j <= last; j++){ if(data[i] > data[j]) { swapData(&data[i], &data[j]); } } } } int ArrayBinarySearch(int data[], int n, int x) { int left = 0, right = n - 1, center; while(left <= right){ center = (left + right)/2; if(data[center]=x){ return center; }else if(x > data[center]){ left = center + 1; }else if(x < data[center]){ right = center - 1; } } return -1; } int main(int argc, char *argv[]) { int data[MAXSIZE]; int i, x; FILE *fp; scanf("%d", &x); fp = fopen(argv[1], "r"); for(i = 0; i < MAXSIZE; i++) { if (fscanf(fp,"%d", &data[i]) == EOF) break; } simpleSort(data, 0, i-1); printf("%d", ArrayBinarySearch(data, i, x )); return 0; } 数値が書かれたファイルを読み込んでソートした後に二分探索を行うプログラムをつくったのですが、うまく動きません。 どこがおかしいか教えてください。 お願いいたします。 ちなみに関数ArrayBinarySearchは目的の値が見つかれば配列中でのインデックスを、見つからない場合は-1を返す関数にしているつもりです。

専門家に質問してみよう