1

これは小さな質問であり、難しい問題を解決することよりも、配列の使用法を理解することを目的としています。

現在、他の配列のセットと比較したい4つの整数(Neighbors)の配列があります(他のどこにも存在しません-それらを格納する必要はありません)。4つの配列Neighborsのどれが同一であるか知りたいです。よくわからない人として、私の最初の試みはこれを行うことでした:

if (Neighbors == {1, 1, 0, 0})
{
    //code...
}
else if (Neighbors == {0, 1, 1, 0})
{
    //code...
}
else if (Neighbors == {0, 0, 1, 1})
{
    //code...
}
else if (Neighbors == {1, 0, 0, 1})
{
    //code...
}

ご覧のとおり、整数の順序は重要です。ただし、上記では、中括弧トークンの前に一次式を予期することに関するコンパイラエラーが返されました。

代わりに、私はこれを試しました:

int Sets[4][4] = { {1, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 1, 1}, {1, 0, 0, 1} };
if (Neighbors == Sets[0])
{
    //code...
}
else if (Neighbors == Sets[1])
{
    //code...
}
else if (Neighbors == Sets[2])
{
    //code...
}
else if (Neighbors == Sets[3])
{
    //code...
}

ここで何が起こるかというとNeighbors = {0, 1, 1, 0}、たとえば)Neighbors == Sets[1]がfalseを返す場合でもです。

さて、これを行って理由を考えた後、配列変数は基本的にシーケンスの最初の要素へのポインターであることを思い出しました。右?したがって、上記のコードが機能しない理由がわかります。2つの配列ではなく、2つのメモリアドレスを比較しています。代わりに、私はこのコードを書きました。これは正常に機能します。

    for (int ii = 0; ii < 4; ++ii)
    {
        bool Same = true;
        for (int jj = 0; jj < 4; ++jj)
        {
            if (Neighbors[jj] != Set[ii][jj])
            {
                Same = false;
            }
        }

        if (Same == true)
        {
            //code...
        }
    }

私が知りたいのは、2つのforループを経由せずにこのような配列を比較する方法があるかどうかです。これよりも単純なはずのようです。値が4つしかない場合、forループは特に集中的ではないことはわかっていますが、2つの配列に同じ情報が含まれているかどうかを判断する方が簡単だと思います。各配列が連続したメモリブロックである場合は、これら2つのブロックを調べて、それらが同一であるかどうかを確認できると思います(これは基本的に、forループが実行していることですが、手動で実行する必要があります)。

では、配列の内容を直接、できれば1行のコードと比較する方法はありますか?そうでない場合は、なぜですか?この問題の背後にある科学を理解したいと思います。

4

3 に答える 3

4

質問にC++のタグを付けました。つまり、を使用する必要がありますstd::vector。それはあなたが望むことをする過負荷operator==になっています(2つのベクトルに対して)。

プリミティブ配列を含む、イテレータがあるものなら何でも使用できstd::equalます。std::lexicographical_compare

もちろんoperator==、他のもののためにオーバーロードすることもできます。残念ながら、プリミティブ配列に対してオーバーロードすることはできません。オーバーロード演算子は、少なくとも1つの引数がクラス(または構造体)型である場合にのみ許可されるためです。ただし、これをオーバーライドして、ベクトルと配列を比較することもできます。何かのようなもの:

template<typename T, typename Alloc, size_t S>
bool operator==(std::vector<T, Alloc> v, const T (&a)[S])
{
    return v.size() == S && std::equal(v.begin(), v.end(), a);
}

(これは、ポインターに劣化していない配列を参照して、最初に宣言されたサイズをチェックするため、安全です)

もちろん、これらすべてのメソッドには、要素を1つずつ比較するループが内部に隠されています。しかし、あなたはそれを書く必要はありません。

于 2012-07-03T06:51:34.393 に答える
4

これを行うためのC++の最も簡単な方法は、std :: equal:を使用することです。

#include <algorithm>

C ++ 11の場合:

if (std::equal(begin(Neighbors), end(Neighbors), begin(Sets[0]))
{ /* then they're equal */ }

C ++ 03の場合:

if (std::equal(Neighbors, Neighbors + 4, Sets[0]))
{ /* then they're equal */ }
于 2012-07-03T06:54:12.247 に答える
1

関数を使用できmemcmpます。配列が等しい場合は0を返します。説明は次のとおりです。http ://www.cplusplus.com/reference/clibrary/cstring/memcmp/

于 2012-07-03T06:44:31.437 に答える