配列の確認方法について

このQ&Aのポイント
  • 配列の確認方法について質問です。
  • 配列の重複や欠損を確認する方法を教えてください。
  • フラグを立てて数値の重複を確認する方法についてアドバイスをお願いします。
回答を見る
  • ベストアンサー

配列の確認

【環境】Windows XP、C++ サイズがXの配列があります。 配列は0~X-1の数値が1つずつ入れる目的で作っています。 その配列に値の重複が無く、全ての数値が入っているかを確認する処理なのですが、 自分が考えた方法で問題ないのかを確認してもらえないでしょうか? 処理としては、unsigned long long int型をフラグとして使って、(Xが64以上になる予定は今のところないので・・・、けど64に制限されるのが・・・。) 0が入っていたら1ビット目を立てて、1が入っていたら2ビット目を立てて、(以降最後まで続ける)にしようと思っています。 最終的に立っているフラグの数値が、2の(X+1)乗―1とイコールかを判定。 (←計算間違ってるかも) これで問題ないでしょうか? 他にいい案があれば教えてもらえないでしょうか? 以上、よろしくお願いします。

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

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.6

for (int i = 0; i < X; ++i)   exist[i] = 1; を for (int i = 0; i < X; ++i)   exist[a[i]] = 1; とするだけなのでは ・・・

nyororo-n
質問者

お礼

あ、ほんとだ。 確かにいけそうな感じに見える。 気づかなかったですよ。 ありがとうございます。

その他の回答 (5)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

exist に入っている値は 0 と 1 しかないので「総和でこける」ことはありえません. あ, 「0 で初期化」は必要だったっけな....

nyororo-n
質問者

お礼

再度ありがとうございます。 この手順は、配列の値を全く使っていない気がしていたので、 どこかを記入ミスしているものだと思っていたのですが。 確かにこの手順だと総和でこける事はないのですが、 配列の内容を使っていないので、結果が変わらなく思えるのです。 どこか勘違いしているのでしたらすみません。

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

ANo.3ですが、運悪く幾つかの条件が重なるとチェックをすり抜ける場合がある事が判明。 例えば「6が2つあって16が無く、かつ、7が2つあって17が無い」と言うパターンの時。確率はかなり低いが、無いとは言えない。

nyororo-n
質問者

お礼

おっと、今処理内容を理解しようと見ていたとこだったのですが、そうなのですか・・・。 追記ありがとうです。

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

// int array[0]~array[n]に、0~nまでの数値が重複せずに入っているか調べる // nはX-1とする // OKならtrue、NGならfalseを返す int check(int n) {   int flg = 0,i;   for (i = 0;i <= n;i++) {     flg ^= i ^ array[i];   }   return !flg; } たぶん、std::vector<int>やビットでのフラグ立てより高速。 一番の長所は「コンパイラを選ばない」って事。C++はもちろん、Cでも動く。

回答No.2

 サイズがXのchar 型の配列a[X]を作り、  前領域を0で初期化し、  対象の配列を読んでいき、nが入っていたら、 0<= n <Xであることを確認し、a[n-1]が0でなければ 重複あり、0ならa[n-1]=1とする。  重複なしで、最後まで続けられたらOK  でどうでしょうか。

nyororo-n
質問者

お礼

確かにchar型配列でも問題ないわけですよね。 ありがとうございます。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

「サイズ X の配列 a に 0 から X-1 までの数値を 1つずつ入れる」だけなら for (int i = 0; i < X; ++i) a[i] = i; でいいんだけど, それは望んでいないんですよね. X < 64 であればそれで動くはずです. 一般には std::vector<int> を使って std::vector<int> exist(X); for (int i = 0; i < X; ++i) exist[i] = 1; if (std::accumulate(exist.begin(), exist.end(), 0) == X) { // 全部そろっている } else { // 足りないやつがいる } という感じかな?

nyororo-n
質問者

お礼

回答有難うございます。 まず補足ですが、配列に格納されるデータはユーザが手入力(もしくは入るから読込)するものです。 ですので、入れ間違いが無いかなどを確認するための処理です。 std::accumulateについて知らなかったため、調べてみた結果、 引数の3番目が0だと総和を求める処理になるものみたいですね。 総和だと、3と5で8になる場合や、4と4で8になる場合があるので、 数字が1つずつあるのかわからないと思うのですが、 何か間違っているのでしょうか? よろしくお願いします。

関連するQ&A

  • 配列へのプラス?

    C++のコードを読んでいるところなのですが、 配列に プラスされているコード部の意味がわからずこまっております。 ********************************* unsigned char data1[32]; unsigned char data2[8]; ※ここでdata1, data2に値入力処理 if(memcmp(data1 + 2, data2, 8) != 0){  //処理X } ********************************* 上記のようなコードの「data1 + 2」の部分がよくわかりません。 byte配列にプラスされている2は、数値なのでしょうか?? C++は普段使わないもので、、、呆れるほどアホな質問だとしてもご了承ください。。 どなたかご教授ねがいます。 よろしくお願いいたします。

  • 空いているビットフラグの確認方法

    空いているビットフラグの中で最小のものを見つけたいのですが、 うまい方法がわからず、どのように作成したら良いか、ご教授お願いします。 たとえば、 int nFlg = 0xFF8F; //上位16ビット省略 というフラグの場合、空いている(ビットフラグの無い)箇所は int nFalse = ~nFlg; // = 0x0070 で求められますが、この中から、最小のフラグ位置(0x0010)を求めたいのです。 (未使用のフラグの中から、使えるビットひとつを選びたいのです・・) 総当りしかないでしょうか? よろしくお願いします。

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

    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++; } }

  • 配列について

    こんにちは。 int p[1000]という整数型の配列を作成しました。 例えば、 p[0] = 1; p[1] = 2; p[2] = 3; ・ ・ ・ p[99] = 100; を格納し、配列の長さ?を調べる際、 unsigned int len = 0; while(p[len]!='\0') len++; とすることで調べることが可能でしょうか?p[100]番以降に0が格納されている場合それがナル文字となるのでしょうか? また、char c[1000]と文字列型の配列を作成し、文字列の数値を格納していく場合、一桁であれば要素1個(1Byte?)で格納できますが、二桁以上であれば要素2個以上(2Byte以上←あっていますでしょうか)必要です。 c[0]='1' c[1]='2' c[2]='3' c[3]='4' ・ ・ ・ c[9]='1' c[10]='0' c[11]='1' c[12]='1' ・ ・ ・ ここで問題なのですが、文字列10と文字列11の判別はできないのでしょうか? 110111が連続している場合も値110と値111と判別できないのでしょうか? 値を格納する場合は、整数型のint c[1000]を用意するという事でしょうか? よろしくお願いします。

  • vector配列の重複を無くすには?

    画像処理で各ピクセルごとのRGB値をそれぞれ取得し、 重複を除いた形で全て表示したいと考えています。 (仮に4ピクセルしかないとして、RGB(255,255,0), RGB(255,255,255),RGB(255,255,255),RGB(255,0,255) といった値が取れたときにRGB(255,255,0), RGB(255,255,255),RGB(255,0,255)のみを表示するといった感じです。) 画像ごとにピクセル数が異なり分からないので、 各ピクセルのRGB値を格納するのに動的配列vector<int*> pixelを 用い、そこにred,green,blueそれぞれの値を格納した 配列RGB[3]を格納しようと思い以下のように書いたのですが、 vector配列に配列を格納したときに重複を削除する方法が 分からず困っています。 for(int x = 0; x->width; x++) { for(int y = 0; y->height; y++) { /*getRGBはそのピクセルのRGB値を取得する仮想関数*/ RGB[0] = (int)getRGB(x,y,RED); RGB[1] = (int)getRGB(x,y,GREEN); RGB[2] = (int)getRGB(x,y,BLUE); } } pixel.push_back(RGB); と格納しても、そこからpixel配列に格納された物の中から RGBが全て一致するものを消去する方法が分かりません。 格納していたものが配列でなければ、pixelをsortして、 unique関数で重複を無くせるのでしょうが… どなたか良い方法をご教授願えませんでしょうか?

  • 【C++】巨大なビット配列の用意の仕方

    現在C++で数値計算用のプログラムを組んでいます。 その計算の中で、2^16個の「on」または「off」のデータをメモリに記憶させる必要があります。その一つ一つにわざわざintやshortなどの既存のデータ型を使うのは馬鹿らしいので、2^16桁の二進数列(=8.2KB程度)を用意して操作したいと思っています。 (もし仮にon=+1,off=0などとしてint型配列を使うと、262KB必要となり、いくつも宣言することがためらわれます。この2^16個のデータを収める「配列」は全部で8000個程度用意したいのです。) これだけ大きなビット配列を、C++で用意するにはどうしたらよいでしょうか? 試しにビットフィールドを用いて struct bit{ unsigned elm :1<<16;  //2^16個のビット数列 }; と宣言してみたのですが、基本型のビット数を超えるからとコンパイルは通りませんでした。@VC++ リソースを活用するためにビット配列を扱った経験のある方など、どうかご教授よろしくお願いします。

  • 関数先にて配列の長さを取得する方法

    関数にて、引数にて渡された配列(ポインタ)から配列数を調べる方法はないでしょうか? #include <stdio.h> void test(unsigned int *p){ printf ("%d\n", sizeof(*p)/sizeof(p[0])); //結果 1 } int main(){ unsigned int hoge[] = {0x30, 0x31,0x32}; test(hoge); printf("%d", sizeof(hoge)/sizeof(hoge[0])); //結果3 return 1; } 上記コードの関数testの*pから配列の数3が抜き取りたいと思っております。 よろしくお願いします。

  • 配列から構造体へデータコピー

    配列から構造体へデータのコピーをしたいのですが、 構造体のメンバがビットフィールドで構成されている時の処理がわかりません。 --------test.c----------- #include <stdio.h> #include <string.h> typedef struct{ unsigned char aaa :1; unsigned char bbb :1; unsigned char ccc :1; unsigned int ddd :13; unsigned char eee :2; unsigned char fff :2; unsigned char ggg :4; }test_t; int main(void) { test_t test_t; unsigned char data[]={0x5F, 0xFE, 0x1C}; memcpy(&test_t, data, 4); printf("aaa = %X\n", test_t.aaa); printf("bbb = %X\n", test_t.bbb); printf("ccc = %X\n", test_t.ccc); printf("ddd = %d\n", test_t.ddd); printf("eee = %X\n", test_t.eee); printf("fff = %X\n", test_t.fff); printf("ggg = %X\n", test_t.ggg); return 0; } ------期待出力--------- aaa = 0 bbb = 1 ccc = 0 ddd = 1FFE eee = 0 fff = 1 ggg = 12 「test.c」を実行した時に「期待出力」のような出力を期待していたのですが、実際には aaa = 1 bbb = 1 ccc = 1 ddd = 1 eee = 0 fff = 0 ggg = 0 と表示されてしまいます。 ビットフィールドで構成された構造体に、配列の値をそのままあてる事は出来ないのでしょうか? 出来るだけ、マスクやシフト演算を使用しないで、配列からビット単位で値を抽出したいのですが・・・

  • C言語のfwrite関数について

    現在,バイナリのデータを処理するプログラムを作成しています。 おおまかに言えば,ファイルA(バイナリモードでオープン)からバイナリでデータを読み込んできて,そのデータを処理してファイルB(バイナリモードでオープン)に書出す,のようなプログラムです。 その処理したデータを入れるデータ型にunsigned long long int型(64bit)を使用しています。 その処理データをファイルBに書出す時に,fwrite関数を用いています(例参照)。 (例) for(i=0; i<N; i++){ fwrite(&c[i], sizeof(c[i]), 1, fp); } //配列cが「unsigned long long int型」です。 //配列cは最初に"0"で初期化しています。 //fpはファイルポインタです。 しかし,本システムでunsigned long long int型が実際に使用しているのは下位32bitです。 上の例で書出した場合,上位32bitの"0"も書出されていることになるのでしょうか。 書出されたファイルのサイズを見れば,64bit全て書出されているようですが,計算間違いで32bitを超えたところまで何かデータが入っている可能性もあります。 どなたはfwrite関数に詳しい方,ご回答をよろしくお願いします。

  • javaのbyte配列へintなどを埋め込む方法

    javaのbyte配列へintなどを埋め込む方法 java初心者です。データ編集がわからなくて悩んでいます。 下記のコードは"棒読みちゃん"といソフトへのTCPパケットを作成するコードです。 char buf[15]; *((short*)&buf[0]) = 0x0001; *((short*)&buf[2]) = speed; *((short*)&buf[4]) = tone; *((short*)&buf[6]) = volume; *((short*)&buf[8]) = voice; *((char* )&buf[10]) = 2; *((long* )&buf[11]) = len; 同じことをJAVAでしたいのですがわかりません。 (バイト型配列へint,long型を簡単に埋め込む方法がわかりません) よろしくお願いします。 よかったら、こちらもお願いします memcpy(&buf[15],message,strlen(messege)); TCPパケットのようなデータ処理が頻繁にある場合、 このようなコードは、どうしたらいいでしょうか? *((unsigned char* )&buf[15]) = message; CとJAVAになってますが、このような処理を簡単に書けないでしょうか?

    • ベストアンサー
    • Java

専門家に質問してみよう