2011-12-04 10 views
2

私は動的に作成された整数の配列を持っています。インデックス%3 == 0.(たとえば、3,6,9、...)の要素をすべて削除しなければなりません。だから、配列のサイズを減らす最善の方法は何ですか? malloc私はメモリの同じ部分にreallocを使うことができますが、newの演算子はどうですか?このようにすること。すべての要素を左にスライドさせ、すべての要素をゼロにしますか?新規および配列サイズ

+0

STLを使用すると、これがすべて実行されます。 –

+0

一般に、 'realloc'はメモリの同じ部分を再利用しません。 –

+1

C++標準ライブラリを使用します。それはあなたのためにすべてのことを行い、何十年も非難されているわけではありません。 –

答えて

2

新しい小さな配列を割り当ててから要素をコピーするだけです。このようなもの(これは0のインデックスにある要素を含みます):

int* array = new int [original_size]; 

// fill array 

size_t new_size = original_size - original_size/3 - 1; // i think i got this right, untested 
int* new_array = new int [new_size]; 

for (int i = 0, int j = 0; i < original_size; i++) 
{ 
    if (i % 3 == 0) 
    { 
     new_array[j] = array[i]; 
     j++ 
    } 
} 

delete [] array; 
array = new_array; 
new_array = nullptr; 

もちろん、要素を左にシフトしてシフトすることができます。しかし、new[]によって割り当てられた配列の一部を削除することはできません。

これは練習問題で、STLを使用することはできませんので、自分で単純なベクトルクラスを実装しようとしないのはなぜですか?

+0

私はそれがちょうど 'original_size - original_size/3'だと思います。サイズは0,1,2,3,4,5,6でチェックしてください。 –

+0

また、OPは「これは運動の一部です」と言っていますので、私は宿題のように扱い、ストレートコードを避けます。 –

+0

@MooingDuck見てみましょう、配列0..6(7要素)から要素0、要素3、要素6、要素3を削除します。新しい配列には4つの要素があるので、7 - 7/3 = 5は正しくありません。 – jrok

3

#include <algorithm> 
#include <iostream> 
#include <vector> 

bool IsDividedByThree (int i) { return ((i%3)==0); } 

int RandomNumber() { return (rand()%100); } 

int main() 
{ 
    std::vector<int> myInts(50); 

    std::generate(myInts.begin(), myInts.end(), RandomNumber); 

    std::copy(myInts.begin(), myInts.end(), std::ostream_iterator<int>(std::cout, " ")); 

    myInts.erase(std::remove_if(myInts.begin(), myInts.end(), IsDividedByThree), myInts.end()); 

    std::copy(myInts.begin(), myInts.end(), std::ostream_iterator<int>(std::cout, " ")); 

} 

STLはあなたのためにすべてを気にかかることをとても素敵ではないですか?

フム1は、STLを使用しないを余儀なくされているコメントを、表示されませんでした。

Cバージョン:

int *temp = new int[NEW_SIZE]; 
    memcpy(temp , old_array, size_of_old_array * sizeof(int)); 
    delete[] old_array; 
    old_array = temp; 
  1. アレイ動的
  2. を作成し、新しいサイズ
  3. で新しい配列を作成
  4. 二番目の配列に最初から要素をコピー、削除最初の配列
  5. 最初の配列へのポインタを2番目の配列にリダイレクト

これらの回答はすべてです。したがって、配列サイズを小さくする最も良い方法は何ですか? - 私はあなたがすでにあなたの問題の残りの部分を解決する方法を知っていると仮定しました。

+0

ありがとう、ありがとう。これは可能な答えの1つです。 – Ockonal

+0

ただし、このソリューションはPODタイプでのみ動作することが保証されています。任意の(コピー可能な)型の配列には 'memcpy'の代わりに' std :: copy'を使います。また、C++ 11では、オブジェクトをコピーするのではなく、オブジェクトを移動する必要があることに注意してください。 – celtschk

+0

@celtschk OPはどのSTLも使用できないと思うので、元の回答を削除しました。 – FailedDev

0

データ要素を0に設定するだけで解放しないでください。また、サイズ変更された配列に新しいメモリを割り当てるときは、前のメモリからすべての要素をコピーする必要があります。

リンクリストとして実装することをお勧めします。

0

placement new operatorはC++で使用できます。 (が必要です)。たとえば、

#include <new> 

int main(int argc, char **argv) { 
    double *b = new double[10]; 
    new(b) double[8]; 

    delete [] b; 
} 
+2

まず第一に、それは問題を解決しません。第二に、それは本当に混乱しています。第三に、それは未定義の振る舞いです。 –

+0

@MooingDuck最初の2つの理由は聞こえます。三番目はどうですか?なぜこれが未定義の動作につながるのでしょうか?もっと説明していただけますか?ありがとう。 –

+0

私は電話から標準を引用することはできませんが、定義されていない動作は、既に構築されたオブジェクトのコンストラクタを呼び出します(デストラクタも同じです)。実際には、charsは例外である可能性があります。そうであれば、他のプリミティブやPODが例外である可能性があります。これがUBかどうかを調べるには、標準をチェックする必要があります。 –

関連する問題