整数データの配列から同じ値のデータを削除する関数

このQ&Aのポイント
  • C言語で整数データの配列から同じ値のデータを削除する関数 int remove_same_data(int a[], int size)を作成する。この関数は重複したデータを削除して残った個数(整数)を関数の戻り値として返す。
  • 関数内で与えられた整数配列をソートし、重複したデータを削除する方法について説明します。削除された後の配列の要素数を戻り値として返します。
  • 与えられた整数配列をソートし、重複したデータを削除する関数を作成します。削除後の配列の要素数を戻り値として返します。
回答を見る
  • ベストアンサー

整数データの配列から同じ値のデータを削除する関数

C言語で整数データの配列から同じ値のデータを削除する関数 int remove_same_data(int a[],int size)を作成する。 但し、この関数は重複したデータを削除して残った個数(整数)を関数の戻り値として返すものとする。 ちなみにここまで出来ました。 下にある途中の1,2,3ができればこのプログラミングができると思うんですが… 分かる方は知恵を貸してください。よろしくお願いします。 #include<stdio.h> void swap_array(int a[], int size, int i) { int t; if(i>=0 && i<size-1){ t=a[i];a[i]=a[i+1];a[i+1]=t; } } void mysort(int a[], int size) { int i,j; for(j=size-1;j>0;j--){ for(i=0;i<j;i++){ if(a[i]>a[i+1]) swap_array(a,size,i); } } } int remove_same_data(int a[], int size) { 1.sort 2.重複部分を削除する 3.残ったデータの個数を返す } int main() { int a[]={3,5,2,3,4,2,3,3,6,6,1,2,2,3,5,8,2,9}, size=18; int i,newsize; newsize = remove_same_data(a, 18); for(i=0;i<newsize;i++){ printf(" %d ", a[i]); } return(0); } 1はこれを使えば出来るらしいのですがよく分かりません。 void swap_array(int a[], int size, int i) { int t; if(i>=0 && i<size-1){ t=a[i];a[i]=a[i+1];a[i+1]=t; } } void mysort(int a[], int size) { int i,j; for(j=size-1;j>0;j--){ for(i=0;i<j;i++){ if(a[i]>a[i+1]) swap_array(a,size,i); } } } 2はこれを使えばできるらしいのですがなかなかできません。 #include<stdio.h> int main() { int a[8]={1,3,3,4,4,5,6,6},size=8; //ソート済みデータの重複の削除 int i,j,p; p=a[0]; //前のデータの記憶 j=0; //削除するデータ数を数える for(i=1;i<size;i++){ if(p==a[i]){ j=j+1; } else{ a[i-j]=a[i];//削除するデータ数分前へ p=a[i]; } } //配列の表示 for(i=0;i<size-j;i++){ printf("%3d ", a[i]);//ここで1,3,4,5,6と表示される } return(0); }

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

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.2

★質問者さんへ。 >ちなみにここまで出来ました。 >下にある途中の1,2,3ができればこのプログラミングができると思うんですが… >分かる方は知恵を貸してください。よろしくお願いします。  ↑  swap_array()…正しい  mysort()…正しい  remove_same_data()…1.2.3 の通りに処理を記述すればよいだけです。  処理手順は >2はこれを使えばできるらしいのですがなかなかできません。  ↑  これで良いと思います。 ・よってもう正しく重複データを削除できると思います。  何をアドバイスすればよいのでしょうか?  私も『補足要求』しますね。 ・ちなみに remove_same_data() 関数は 1.2.3 の手順どおりに  int remove_same_data( int a[], int size )  {   int i, j, p;      // ソート   mysort( a, size );      //ソート済みデータの重複の削除   p = a[0]; //前のデータの記憶   j = 0; //削除するデータ数を数える   for ( i = 1 ; i < size ; i++ ){    if( p == a[i] ){     j = j + 1;    }    else{     a[ i - j ] = a[ i ];//削除するデータ数分前へ     p = a[ i ];    }   }   return size - j;  }  ↑  で良いでしょう。 ・それでは。また。

その他の回答 (3)

回答No.4

下の回答者です。 すみません。自分の勘違いでしたね。 このプログラムで正解です。 申し訳ありませんでした。

回答No.3

***** はじめまして ***** >2はこれを使えばできるらしいのですがなかなかできません。 少々細かいところでミスをされているようです。 おそらく実験?的に用意した配列{1,3,3,4,4,5,6,6}を元に実行した結果、1,3,4,5,4と標示されるのではないでしょうか? 重要なのは最後に重複して発見された数字の処理です。このプログラムでは次の値が重複でないときに初めて的確な位置に挿入されるため、最後に重複した文字は正しい位置に挿入されません。 よって示されたプログラムを少々変更する必要があります。 ***** 提示していただいたプログラム ***** for(i=1;i<size;i++){ if(p==a[i]){ j=j+1; } else{ a[i-j]=a[i];//削除するデータ数分前へ p=a[i]; } } ***** 修正したプログラム ***** (見やすくするため、全角のスペースを入力します) for(i=1; i<size; i++){   if(p==a[i]){      j=j+1;      if(i == (size - 1))        a[i-j]=a[i];   }   else{   a[i-j]=a[i];//削除するデータ数分前へ   p=a[i];   } }

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.1

もう出来ておるようにお見受けしますが。

関連するQ&A

  • 4つの異なる二次配列を関数で表示

    二次配列と関数の問題です。 [日本語訳]displayArray7を呼ぶ関数を書きなさい。その関数は二次配列を一つの引数として受け取り、その内容を画面に表示すべきである。その関数は下のいずれの配列でも動作するようにしなさい。プログラムを書いてその関数を評価しなさい。 4つの配列とも一次の項(?)の数が違うじゃないですか。しかも関数を呼ぶときは配列[5][7]などはいらないですよね? (displayArray7(hours);だけ) だから、各配列の一次の項がどんな数字を持っているのかを関数displayArray7に送ることが出来ず、どのように表示してよいのか分かりません(今は一応最大値50で表示しています)。どのようにすればよいのでしょうか? 教えてください。お願いします。 #include <iostream> using namespace std; void initialize(int array[][7]); void displayArray7(int array[][7]); int main() { int hours[5][7]; int stamps[8][7]; int autos[12][7]; int cats[50][7]; initialize(hours); displayArray7(hours); initialize(stamps); displayArray7(stamps); initialize(autos); displayArray7(autos); initialize(cats); displayArray7(cats); return 0; } void initialize(int array[50][7]) { int i, j; for(i=0; i<50; i++) for(j=0; j<7; j++) array[i][j] = 0; } void displayArray7(int array[][7]) { int i, j; cout << "\t1\t2\t3\t4\t5\t6\t7" << endl << endl; for(i=0; i<50; i++){ cout << i+1 << ":"; for(j=0; j<7; j++){ cout << "\t" << array[i][j]; } cout << endl << endl; } }

  • C言語 ソートについて

    #include <stdio.h> #include <stdbool.h> #define NUM_ARRAY 4 #define NUM_DATA 5 int count_swap = 0; // 交換回数 int count_comparison = 0; // 比較回数 void selection_sort(int a[], int n) { } int main(void) { int data[NUM_ARRAY][NUM_DATA] = {{9, 7, 5, 6, 8}, {9, 8, 7, 6, 5}, {5, 6, 7, 8, 9}, {5, 6, 8, 7, 9}}; for (int i = 0; i < NUM_ARRAY; i++) { count_swap = 0; count_comparison = 0; int d[NUM_DATA]; copy_array(data[i], d, NUM_DATA); // 配列のコピー printf("----------------\n"); print_array(d, NUM_DATA); // ソート前の配列の表示 selection_sort(d, NUM_DATA); // 挿入ソートの実行 print_array(d, NUM_DATA); // ソート後の配列の表示 printf("比較回数: %d\n", count_comparison); // 比較回数の表示 printf("交換回数: %d\n", count_swap); // 交換回数の表示 } } 上の雛形を使って選択ソートを実行するという問題なのですが途中までそれっぽいのは出来たのですが上手くいかないので解答をお願いします。 下に自分が今書いているものを置いておきます。 #include <stdbool.h> #include <stdio.h> #define NUM_ARRAY 4 #define NUM_DATA 5 int count_swap = 0; int count_comparison = 0; void swap(int d[], int i, int j) { count_swap += 1; printf("swap a[%d] = %d, a[%d] = %d\n", i, d[i], j, d[j]); int temp = d[i]; d[i] = d[j]; d[j] = temp; } void copy_array(int *a, int *b, int n) { for (int i = 0; i < n; i++) { b[i] = a[i]; } } void print_array(int d[], int n) { for (int i = 0; i < n; i++) { printf("%d ", d[i]); } printf("\n"); } bool compare(int d[], int i, int j) { count_comparison += 1; printf("compare a[%d] = %d, a[%d] = %d\n", i, d[i], j, d[j]); if (d[i] > d[j]) { return true; } else { return false; } } void selection_sort(int d[], int n) { int min; for (int i = 0; i < n - 1; i++) { min = i; for (int j = i + 1; j < i; j++) { if (compare(d, min, j)) { min = j; } } swap(d, i, min); print_array(d, n); } } int main(void) { int data[NUM_ARRAY][NUM_DATA] = { {9, 7, 5, 6, 8}, {9, 8, 7, 6, 5}, {5, 6, 7, 8, 9}, {5, 6, 8, 7, 9}}; for (int i = 0; i < NUM_ARRAY; i++) { count_swap = 0; count_comparison = 0; int d[NUM_DATA]; copy_array(data[i], d, NUM_DATA); // 配列のコピー printf("----------------\n"); print_array(d, NUM_DATA); // ソート前の配列の表⽰ selection_sort(d, NUM_DATA); // 挿⼊ソートの実⾏ print_array(d, NUM_DATA); // ソート後の配列の表⽰ printf("⽐較回数: %d\n", count_comparison); // ⽐較回数の表⽰ printf("交換回数: %d\n", count_swap); // 交換回数の表⽰ } }

  • ソートの時間計算について

    ソートの時間計測について以下のようなプログラムを作成したのですが、ソートはうまく動きますが何度試しても処理時間が0.00000秒となってしまいます。どのように改良すればこのような問題を解決できるのでしょうか。ご回答よろしくお願いいたします。 #include <stdio.h> #include <time.h> #define SIZE 100 void swap(int data[], int s, int t){ int tmp = data[s]; data[s] = data[t]; data[t] = tmp; } void Bsort(int data[], int size) { int i, j; for(i=1; i<size; i++){ for(j=(size-1); j>0; j--){ if(data[j] < data[j-1]){ swap(data, j, j-1); } } } } void Ssort(int data[], int size){ int i, j, k, tmp; for(i=1; i<size; i++){ k = data[i-1]; for(j=i; j<size; j++){ if(k>data[j]){ tmp = k; k = data[j]; data[j] = tmp; } } tmp = k; k = data[i-1]; data[i-1] = tmp; } } void printArray(int ar[], int size) { int i; for (i = 0; i < size; i++) printf("%4d", ar[i]); printf("\n"); } int main(void) { int i, x; int data[SIZE]= {412, 54, 595, 329, 24, 488, 313, 272, 129, 210, 670, 516, 342, 541, 491, 640, 167, 117, 726, 206, 474, 762, 153, 292, 1000, 607, 151, 661, 93, 270, 737, 531, 641, 548, 299, 287, 547, 394, 550, 475, 443, 261, 707, 503, 403, 739, 226, 646, 778, 588, 427, 169, 477, 572, 413, 300, 88, 321, 55, 779, 542, 680, 211, 273, 288, 276, 405, 307, 424, 668, 756, 255, 190, 449, 35, 435, 91, 486, 58, 408, 4, 63, 534, 330, 701, 65, 256, 311, 586, 404, 459, 254, 291, 333, 42, 343, 418, 512, 164, 56}; clock_t t1,t2; printf("番号を入力してください。\n1,Bubble Sort\n2,Selection Sort\n"); scanf("%d", &x); switch(x){ case 1: printf("before:"); printArray(data, SIZE); t1 = clock(); Bsort(data, SIZE); t2 = clock(); printf(" after:"); printArray(data, SIZE); printf("処理時間:%f[ms]¥n", (double)(t2 - t1) / CLOCKS_PER_SEC); break; case 2: printf("before:"); printArray(data, SIZE); t1 = clock(); Ssort(data, SIZE); t2 = clock(); printf(" after:"); printArray(data, SIZE); printf("処理時間:%f[ms]¥n", (double)(t2 - t1) / CLOCKS_PER_SEC); break; } return 0; }

  • C++の関数ポインタについて

    例えば汎用的に整列操作を行えるクラスを作ろうと考えます。 で、以下のようなクラスをでっちあげました。 #include <stdlib.h> #include <stdio.h> #include <vector> using namespace std; template< class T >class Sort{ private: inline void swap( vector< T > data , int i , int j ){ T t = data[ i ]; data[ i ] = data[ j ]; data[ j ] = t; } public: vector< T > Data; Sort( vector< T > data ){ Data = data; } void selection( vector< T > data , int ( *func )( vector< T > data , int i , int j ) ) { int min , N = data.size(); {for( int i = 1; i < N; i++ ){ min = i; for( int j = i + 1; j <= N; j++ ){ if( func( data , min , j ) ){ min = j; } } swap( data , min , i ); }} } static int comp( vector< T > data , int i , int j ){ return data[ i ] >= data[ j ]; } }; void main( void ){ Sort< int > *d; vector< int > data( 20 ); d = new Sort< int >( data ); d->selection( data , d->comp ); return; } 中身は整列ソートだけでとても寂しいですが、教科書的に比較部分を汎用的に関数をユーザーが選んで指定できるようになっています。今回はmainからSortクラスでstaticで宣言したcompを指定していますが、staticにしたくないです。でもなっちゃっているのはstaticを外すとコンパイルエラーになるからです。 staticを外したメンバ関数を指定すると例えばこんなエラーがでます。 エラー E2034 template.cpp 43: 'int (* (_closure )(vector<int,allocator<int> >,int,int))(vector<int,allocator<int> >,int,int)' 型は 'int (*)(vector<int,allocator<int> >,int,int)' 型に変換できない(関数 main() ) エラー E2342 template.cpp 43: パラメータ 'func' は int (*)(vector<int,allocator<int> >,int,int) 型として定義されているので void は渡せない(関数 main() ) なんでこのようなエラーになるのか分かりません。メンバ関数を指定したいのですが、指定の仕方が分かりません。どなたか教えてください。本当に困ってしまっています。

  • C言語プログラムについて

    wikipediaのコムソートを参考に、次のように作りました。 動きますでしょうか。動かなければ、どこをどのようにすればよいか教えていただけませんでしょうか。 プログラム「#include<stdio.h> #include<string.h> void combsort(void); void swap(void); int main(void) { combsort(); swap(); printf("データ%dの並べ替え結果は、\n%d\nです。\n"data2,data); return 0; } void combsort(){ int h,swaps,data,len,data2; printf("ソートさせる数を入力。>\n"); scanf("%d",&data); data2 = data; len = strlen(data); h = len * 10 / 13; while(true){ swapa = 0; for(i = 0;i + h <len;i++) { if(data(i) > data(i + h)) { swap(data, i, i + h); swaps +=1; } } if(h==1){ if(swaps==0){ break; } } else{ h = h * 10 / 13; } } } void swap{ int a,i,j; const int t = a[i]; a[i] = a[j]; a[j] = t; } 」 data:scanfによって入力される並べ替えを行う数値(例:0219523056810)を代入。 data2:dataのコピーで、並べ替えを行う前のデータを保管しておくもの。 また、これの反対(これが、昇順なら、降順。降順なら、昇順。)を同じようにしたいと思います。(combsort2にて)どうすればよいでしょうか。 教えていただけませんでしょうか。 お早めのご回答お待ちしております。

  • プログラミング(配列と関数の引数)

    a : ABCDE a : ABCDEFGH Len : 8 a : FGHIJ a : FGH a : FGH, c : FGH 上記のように表示されるプログラムを作りたいのですが、なかなかできません。下記のようなプログラムを作ったのですがどこが間違っているのかよくわかりません。分かる方、指摘をお願いします。 #include <stdio.h> void my_strcpy(char s[], char t[]); int my_strlen(char s[]); void my_strcat(char s[], char t[]); int main(){ char a[10]; char b[10] = "ABCDE"; char c[] = "FGH"; int len; my_strcpy(a, b); printf("a : %s\n", a); my_strcat(a, c); printf("a : %s\n", a); len = my_strlen(a); printf("Len : %d\n", len); my_strcpy(a, "FGHIJ"); printf("a : %s\n", a); a[3] = '\0'; printf("a : %s\n", a); if(strcmp(a, c) == 0){ printf("a : %s, c : %s\n", a, c); } int i, s, t; my_strcpy(a, b + 2); printf("a : %s\n", a); void my_strcpy(char s[], char t[]){ for (i = 0; t[i] != '\0'; i++){ s[i] = t[i]; } s[i] = '\0'; } int my_strlen(char s[]){ int i; for (i = 0; s[i] != '\0'; i++); return i; } void my_strcat(char s[], char t[]){ int i, j; for (i = 0; s[i] != '\0'; i++); for (j = 0; t[j] != '\0'; i++, j++){ s[i] = t[j]; } s[i] = '\0'; } }

  • 配列

    最後にもう一つだけお願いします。ずっと格闘しても解決できません・・ 配列の中の数字で、偶数を全て奇数の前にもって行きます 例) {1,0,1,0,0,1,1} → {0,0,0,1,1,1,1} {3,3,2} → {2,3,3} {2,2,2} → {2,2,2} 流れとしては、まず奇数の数を数えます。これは何回シフトするから知るためです。 配列0から奇数を探し、あればそれを一番最後の配列へとシフトします。 奇数を探す作業が一度終わっても、まだシフトさせないといけない奇数があるかもしれないので(奇数が連続で並んでる場合)、最初に数えた奇数の数分だけちゃんとシフトするようにしようと思います。 public void evensLeft(int[] array) { int odd=0; for (int i = 0; i < array.length; i++) { if(array[i]%2!=0) odd++; //奇数の個数 } while (odd>0) { //奇数分シフトするためのカウント for(int j=0;j<array.length;j++){ //奇数を探す if (array[j] % 2 != 0) { odd--; //奇数のカウントを1減らす for (int k = j; k < array.length-1; k++) { //その奇数を一番最後に移動 int temp = array[k+1]; array[k+1] = array[k]; array[k] = temp; } } } } return array; } いくつかの例では動くのですが、{3,3,2}の例だと配列0に3が来てしまいます。色々変えてみても結果無理でした・・・ どなたかご教授お願いします。

    • ベストアンサー
    • Java
  • printfの挿入箇所

    #include <stdio.h> #include <stdlib.h> #define N 500 void bubblesort(int h, int k, int *A); void swap(int i, int j, int *A); int main(void) { int A[N]; int n, i; FILE *file; file=fopen("sortdata", "r"); /* データの読込み */ fscanf(file, "%d", &n); if(n>N) { printf("Illegal array size n = %d for N = %d\n", n, N); exit(1); } for(i=0; i<n; i++) fscanf(file, "%d", &A[i]); /**/ printf("A = "); /**/ printf("\n"); bubblesort(0, n-1, A); /* 配列A[0]からA[n-1]の整列 */ return(0); } /* A[k],...,A[h]の要素をバブルソートによって整列 */ void bubblesort(int h, int k, int *A) { int i, j, p; int no; int test; /* test==1; すでに整列済み */ for(i=h; i<k; i++) /* バブル操作の反復 */ { test=1; for(j=k; j>=i+1; j--) { for(no=0; no<j; no++) printf(" %d",A[no]); if(A[j]<A[j-1]) { printf(" > %d ",A[j]); swap(j, j-1, A); test=0; } else { printf(" < %d ",A[j]); } for(no=j+1; no<=k; no++) printf(" %d ",A[no]); printf("\n"); } printf("\n"); if(test==1) return; } return; } /* Swap A[i] and A[j]. */ void swap(int i, int j, int *A) { int temp; temp=A[i]; A[i]=A[j]; A[j]=temp; return; } 以上のプログラムを A = パス1: 7 5 1 2 8 > 3 7 5 1 2 < 3 8 7 5 1 < 2 3 8 7 5 > 1 2 3 8 7 > 1 5 2 3 8 1 7 5 2 3 8 パス2: 1 7 5 2 3 < 8 1 7 5 2 < 3 8 1 7 5 > 2 3 8 1 7 > 2 5 3 8 1 2 7 5 3 8 パス3: 1 2 7 5 3 < 8 1 2 7 5 > 3 8 1 2 7 > 3 5 8 1 2 3 7 5 8 パス4: 1 2 3 7 5 < 8 1 2 3 7 > 5 8 1 2 3 5 5 8 パス5: 1 2 3 5 7 < 8 1 2 3 5 7 8 比較は15回でした。 交換は8回でした。 と表示させたいのですがうまくいきません。 どなたかご指導よろしくお願いします

  • バブルソートについて質問です。

    キーボード入力で10個好きな数字を入れてもらい入力した数字を小さい順に並び替えさらに入力した数を合計して小さい順の入力値と合計値を表示させ0は表示させないというプログラムを作りたいのですが途中から意味が分からなくなってしまいました。 ここを直したらいいなどのアドバイスをお願いします。 #include <stdio.h> void swap (int *,int *); void printdata(int *); main() { int a[10]; int n=10; int i,j; for(i=0;i<=9;i++) scanf("%d\n",a[i]); int kekka; kekka=a+a[1]+a[2]+a[3]+a[4]+a[5]+a[6]+a[7]+a[8]+a[9]; return kekka; printdata(a); for(j=n-1;j>=0;j--){ for(i=0;i<j;i++){ if(a[i]>a[i+1]){ swap(a+i,a+i+1); printf("[%d]と[%d]を入れ替え\n",i,i+1); printdata(a); } } } } void swap(int *y,int *z) { int t; t= *y; *y=*z; *z=t; } void printdata(int *a) { int i; for(i=0;i<=9;i++) printf("%4d",a[i]); printf("\n"); }

  • 配列を使った・・・。

    配列を使って簡単な迷路を作っているのですが、なかなかうまくいきません。 0を" "1を"■"を表示させたいのですがうまくいきません。 何処を直せばいいのか教えてください。 public class Sample1 { public static void main (String[]args) { int [][] data = { {1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1}, {1,0,1,1,0,0,0,1,1,1,0,1,1,1,1,1,0,1,1,1}, {1,0,0,0,0,1,0,0,0,1,0,0,0,1,1,1,0,1,1,1}, {1,1,1,1,1,1,1,1,0,1,0,1,0,1,1,0,0,1,1,1}, {1,1,1,1,1,0,0,0,0,1,0,1,0,0,0,0,1,1,1,1}, {1,1,1,1,1,0,1,1,0,0,0,1,1,1,1,1,1,1,1,1}, {1,1,1,1,0,0,1,1,0,1,0,1,1,1,0,1,1,1,1,1}, {1,1,1,1,0,1,1,1,1,1,0,1,1,1,0,0,0,1,1,1}, {1,1,1,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1}, {1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} }; for (int i=0; i<10; i++) { for (int j=0; j<20; j++) { System.out.print(data [i][j]); } if(data [i][j] = 1){ System.out.println("■"); }else{ System.out.println(" "); } } } }

    • ベストアンサー
    • Java

専門家に質問してみよう