21 Stimmen

Wie prüft man in C++, ob ein Vektor eine Teilmenge eines anderen Vektors ist?

Ich versuche, einen einfachen Weg zu finden, um zu prüfen, ob ein Vektor eine Teilmenge eines anderen ist, ohne die Reihenfolge der Elemente im Vektor zu sortieren. Beide Vektoren enthalten Elemente mit Zufallszahlen.

std::includes scheint nur für sortierte Bereiche zu funktionieren. Wie kann ich dies bewerkstelligen?

1 Stimmen

Was ist, wenn Vektor 1 Duplikate hat? Muss auch Vektor 2 ähnliche Duplikate haben?

1 Stimmen

Warum müssen Sie das tun? Was ist so schlimm daran, sie zu sortieren?

2 Stimmen

Klingt so, als hätten Sie sich eine std::set möglicherweise in erster Linie. Sind Sie sicher dass std::vector ist das, was Sie wollen?

35voto

Benjamin Lindley Punkte 99114

Kopieren Sie die Vektoren. Sortiere die Kopien. Verwende dann std::includes auf den Kopien.

template <typename T>
bool IsSubset(std::vector<T> A, std::vector<T> B)
{
    std::sort(A.begin(), A.end());
    std::sort(B.begin(), B.end());
    return std::includes(A.begin(), A.end(), B.begin(), B.end());
}

10 Stimmen

"Ich suche nach einer einfachen Methode, um zu prüfen, ob ein Vektor eine Teilmenge eines anderen Vektors ist, ohne die Reihenfolge der Elemente im Vektor zu sortieren." Wenn Sortieren die Antwort ist, war Ihre Frage sehr, sehr schlecht.

4 Stimmen

@Benjamin: Weil Sie die Frage nach "finden... ohne zu sortieren..." nicht beantwortet haben, wie Tomalak sagte.

1 Stimmen

@arasmussen: Es scheint, dass die Anforderung "ohne Sortierung" ein Symptom für ein zugrundeliegendes Problem ist, das der Auftraggeber nie ganz verstanden hat. Er beschrieb etwas, das er tun wollte, aber nicht, was er tatsächlich zu erreichen versuchte. Ich habe schon Fragen gesehen (und ich habe mich auch schon solcher Dinge schuldig gemacht), bei denen der Fragesteller nach einer Sache fragte, weil er dachte, das sei die Lösung, aber es gab eine viel einfachere Lösung, die keine seltsamen Anforderungen erforderte.

9voto

Meine Antwort geht davon aus, dass Sie, wenn Sie "Teilmenge" sagen, eigentlich eher nach dem Äquivalent einer "Teilzeichenkette" suchen, d. h. die Reihenfolge der Elemente während der Suche beibehalten.


Letztendlich kann ich mir nicht vorstellen, wie man das in weniger als O(n*m) . Da kann man ganz einfach seine eigene Rolle spielen:

template <typename T1, typename T2>
bool contains(std::vector<T1> const& a, std::vector<T2> const& b) {
   for (typename std::vector<T1>::const_iterator i = a.begin(), y = a.end(); i != y; ++i) {
      bool match = true;

      typename std::vector<T1>::const_iterator ii = i;
      for (typename std::vector<T2>::const_iterator j = b.begin(), z = b.end(); j != z; ++j) {
          if (ii == a.end() || *j != *ii) {
              match = false;
              break;
          }
          ii++;
      }

      if (match)
         return true;
   }

   return false;
}

Live-Demo.

(Sie könnten wahrscheinlich kreativer mit den Parametern der Vorlage umgehen).

0 Stimmen

2011 war eine beängstigende Zeit für C++!

2voto

Andrew Rasmussen Punkte 14459

Dabei wird davon ausgegangen, dass Duplikate KEINE Rolle spielen. Wenn Sie also zwei Instanzen der Zahl 99 in Vektor a haben, dann wird Vektor b als Teilmenge deklariert, solange er mindestens eine Instanz der Zahl 99 enthält.

bool isSubset(const std::vector<int>& a, const std::vector<int>& b)
{
    for (std::vector<int>::const_iterator i = a.begin(); i != a.end(); i++)
    {
        bool found = false;

        for (std::vector<int>::const_iterator j = b.begin(); j != b.end(); j++)
        {
            if (*i == *j)
            {
                found = true;
                break;
            }
        }

        if (!found)
        {
            return false;
        }
    }

    return true;
}

1 Stimmen

Anstelle von n*log(n) Komplexität hat die vorgeschlagene Lösung also n^2 Komplexität (und es ist auch ein schlechtes C++)

0 Stimmen

Er hat die Komplexität nicht erwähnt, und dies ist meiner Meinung nach eine sehr einfach zu verstehende Lösung

0 Stimmen

@Gene: Wie wollen Sie die O(n log m) ? Die Eingabe ist nicht sortiert. Das Beste, worauf Sie hoffen können, ist die Abschreibung O(n*m) bin ich mir sicher.

0voto

thayne Punkte 376

Ohne Sortierung...

template <typename T>
bool isSubsetOrEqual(std::vector<T> const& a, std::vector<T> const& b) {
   for(auto const& av:a){
      if(std::find(b.begin(),b.end(),av)==b.end())
          return false;
   }
   return true;
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X