1

C++ プロジェクトに関する支援が必要です。私がしなければならないことは、ポインターの配列から特定の要素を削除することです。私に教えられたテクニックは、要素を 1 つ減らして新しい配列を作成し、指定された要素を除いて古い配列からすべてを新しい配列にコピーすることです。その後、古い配列を新しい配列に向ける必要があります。

ここに私がすでに持っているもののいくつかのコードがあります:

ところで、私はカスタム構造体を扱っています...

Data **values = null;    // values is initialized in my insert function so it is
                         //   populated
int count;               // this keeps track of values' length



bool remove(Data * x) {
    Data **newArray = new Data *[count - 1];

    for (int i = 0; i < count; i++) {
        while (x != values[i]) {
            newArray[i] = values[i];
        }
        count -= 1;
        return true;
    }
    values = newArray;

    return false;
}

これまでのところ、挿入関数は機能し、入力された配列を出力しますが、削除を実行すると、配列が小さくなりますが、目的の要素は削除されません。コントロールとして毎回0番目の要素を使用しています。

これは私が得てきた出力です:

count=3 values=[5,6,7]            // initial insertion of 5, 6, 7
five is a member of collection? 0
count=3 values=[5,6]              // removal of 0th element aka 5, but doesn't work
five is a member of collection? 0
count=4 values=[5,6,5]            // re-insertion of 0th element (which is stored in
five is a member of collection? 0 // my v0 variable)

これを完了するための正しい方向に私を微調整できますか?

4

2 に答える 2

3

まず第一に、あなたのコードは無駄にメモリをリークしています! 次に、最初の要素のみをコピーし、最初の要素がたまたま削除したい要素である場合でもコピーしません。また、関数から戻ったとき、内部状態はまったく変更されていません。あなたは間違いなくその線に沿って何かをしたい

Data** it = std::find(values, values + count, x);
if (it != values + count) {
     std::copy(it + 1, values + count, it);
     --count;
     return true;
}
return false;

std::vector<T>そうは言っても、すべての操作に再割り当てを含めるようなことを誰かが実装するように教えてくれた場合は、学校を変える時が来ました! メモリ割り当ては比較的コストがかかるため、避けたい場合。つまり、 のようなものを実装する場合、実際には!std::vector<T>のように実装したいと考えています。std::vector<T>つまり、存在するよりも潜在的に多くの要素の内部バッファーを保持し、使用している要素の数を覚えています。新しい要素を挿入するときは、現在の配列にスペースがない場合にのみ新しい配列を割り当てます (そうしないと、常に最後に要素を追加する場合でも簡単に 2 次複雑度が発生します)。要素を削除するときは、後続のすべてのオブジェクトを 1 つ上に移動するだけで、配列内のオブジェクトが 1 つ少ないことに注意してください。

于 2012-09-16T01:44:50.627 に答える
0

これを試して:

bool remove(Data * x)
{
    bool found = false;

    // See if x is in the array.
    for (int i = 0; i < count; i++) {
        if (x != values[i]) {
            found = true;
            break;
        }
    }

    if (!found)
    {
        return false;
    }

    // Only need to create the array if the item to be removed is present
    Data **newArray = new Data *[count - 1];

    // Copy the content to the new array
    int newIndex = 0;
    for (int i = 0; i < count; i++)
    {
        if (x != values[i])
            newArray[newIndex++] = values[i];
    }

    // Now change the pointers.
    delete[] values;
    count--;
    values = newArray;
    return true;
}

xが配列に存在する場合、それは一度しか存在しないという根本的な仮定があることに注意してください! このコードは、複数のオカレンスに対しては機能しません。それは、これが学校の演習であることを考えると、あなたに任されています。

于 2012-09-16T02:25:11.260 に答える