webentwicklung-frage-antwort-db.com.de

Vergleichen Sie den kleineren Vektor mit dem größeren, um zu prüfen, ob er sich am Ende des kleineren Vektors unterscheidet

Wir haben zwei Größenvektoren, die von der Laufzeit abhängen, und müssen überprüfen, ob sie gleich sind - unterscheiden sich Elemente erst nach dem Ende eines kleineren Vektors. Ich habe std :: equal verwendet, aber das Problem ist, dass ich zuerst herausfinden muss, welcher Vektor eine kleinere Größe hat, was zu einer zusätzlichen Codezeile führt:

#include <vector>
#include <iostream>

int main()
{
  std::vector<int> a(1000, 3);
  std::vector<int> a1(100, 3);

  if(a.size() > a1.size())
  {
    if(std::equal(a1.begin(), a1.end(), a.begin()))
    {
      std::cout << "Same a gt a1" << std::endl;
    }
  }

  if(a1.size() > a.size())
  {
    if(std::equal(a.begin(), a.end(), a1.begin()))
    {
      std::cout << "Same a1 gt a" << std::endl;
    }
  }

  if(a1.size() == a.size())
  {
    if(std::equal(a.begin(), a.end(), a1.begin()))
    {
       std::cout << "Same a = a1" << std::endl;
    }
  }
}

Kann der Code zum Vergleich von zwei Vektoren verbessert werden oder sich nur am Ende eines kleineren Vektors unterscheiden?

13
Programmer

Sie benötigen nur einen Aufruf von std::equal, wenn Sie zuvor die kleinere Größe berechnen. Ich würde den Code so umgestalten:

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

int main()
{
    std::vector<int> a(1000, 3);
    std::vector<int> a1(100, 3);

    if (std::equal(a1.begin(), a1.begin() + std::min(a.size(), a1.size()), a.begin())) 
    {
        std::cout << "Same" << std::endl;
    }
    return 0;
}

Wenn Sie die zweite Information darüber behalten möchten, welcher Vektor größer ist, können Sie dies beispielsweise folgendermaßen erreichen:

std::cout << "Same " << ((a.size() == a1.size())? "a = a1" : ((a.size() > a1.size())? "a gt a1" : "a1 gt a")) << std::endl;
8
Blaze

Seit C++ 14 können Sie std::mismatch verwenden und das zurückgegebene Iteratorpaar am Ende jedes Bereichs überprüfen:

auto it = std::mismatch(a.begin(), a.end(), a1.begin(), a1.end());
if (it.first == a.end() || it.second == a1.end()) {
    // Equality
}

Sie erfahren auch, wo die Elemente beginnen, sich zu unterscheiden, und wenn nicht, dann ist der größere Vektor größer (der Anfang des Unterbereichs, den Sie nicht vergleichen möchten).

23
Nelfeal

Hier ist eine reine C++ 11-Lösung, die für jeden sequentiellen Container (z. B. std::vector, std::list, std::deque) funktionieren sollte. Es verwendet einen benutzerdefinierten Rückgabetyp, da der Vergleichstyp, den Sie in den ursprünglichen Snippets anzeigen, mehr Informationen enthält, als ein einfacher boolescher Wert enthalten kann.

enum class CombinedCompareResult {
   NotEqual, EqualAndFirstLarger, EqualAndSecondLarger, EqualIncludingSize
};

template <class Rng1, class Rng2>
CombinedCompareResult combinedCompare(const Rng1& rng1, const Rng2& rng2)
{
   using std::begin;

   const auto elementsToCompare = std::min(rng1.size(), rng2.size());

   if (!std::equal(begin(rng1), std::next(begin(rng1), elementsToCompare), begin(rng2)))
      return CombinedCompareResult::NotEqual;
   else if (rng1.size() == rng2.size())
      return CombinedCompareResult::EqualIncludingSize;
   else if (rng1.size() > rng2.size())
      return CombinedCompareResult::EqualAndFirstLarger;
   else
      return CombinedCompareResult::EqualAndSecondLarger;
}

Dies kann wie folgt verwendet werden und sollte zu dem gleichen Verhalten wie der Code in der Frage führen.

const auto cmp = combinedCompare(lst, a);

if (cmp == CombinedCompareResult::EqualIncludingSize)
    std::cout << "Same a = a1" << std::endl;
else if (cmp == CombinedCompareResult::EqualAndFirstLarger)
    std::cout << "Same a gt a1" << std::endl;
else if (cmp == CombinedCompareResult::EqualAndSecondLarger)
    std::cout << "Same a1 gt a" << std::endl;
0
lubgr