C RUBY-ON-RAILS MYSQL ASP.NET DEVELOPMENT RUBY .NET LINUX SQL-SERVER REGEX WINDOWS ALGORITHM ECLIPSE VISUAL-STUDIO STRING SVN PERFORMANCE APACHE-FLEX UNIT-TESTING SECURITY LINQ UNIX MATH EMAIL OOP LANGUAGE-AGNOSTIC VB6 MSBUILD

# Find the unique elements of a vector C++

By : Kevin Villasana
Date : October 24 2020, 06:10 PM
around this issue So for small enough n (<=1e8) sorting and removal (using std::sort() and std::unique) approach is still faster than hash tables.
Sample code: O(n log n)
code :
``````vector<int>A = {1,2,3,1,2,5};
sort(A.begin(),A.end());
A.erase(unique(A.begin(),A.end()),A.end());
for(int&x:A)
cout<<x<<" ";
``````

Share :

## C++, fast remove elements from vector unique to another vector

By : Kalos
Date : March 29 2020, 07:55 AM
this will help There are two tricks I would use to do this as quickly as possible:
code :
``````std::unordered_set<int> toRemove = /* ... */
v1.erase(std::remove_if(v1.begin(), v1.end(), [&toRemove] (int x) -> bool {
}, v1.end());
``````

## Find the indices of last occurrence of the unique elements in a vector

By : user2981801
Date : March 29 2020, 07:55 AM
like below fixes the issue I have an unordered vector v like the one shown below and would like to find the indices of the last occurrence of every unique elements in the list. , Another approach that works even if the data are not ordered:
code :
``````length(v1)-match(unique(v1),rev(v1))+1
``````

## Find unique set of strings in vector where vector elements can be multiple strings

By : ES B
Date : March 29 2020, 07:55 AM
With these it helps I have a series of batch records that are labeled sequentially. Sometimes batches overlap. , A little bit shorter:
code :
``````x <- c("1","1","1/2","2","3","4","5/4","5")
x<-data.frame(x=x, period=-1, stringsAsFactors = F)
period=0
prevBatch=-1
for (i in 1:nrow(x))
{
spl=unlist(strsplit(x\$x[i], "/"))
currentBatch=min(spl)
if (currentBatch<prevBatch) { stop("Error in sequence") }
if (currentBatch>prevBatch)
period=period+1;

x\$period[i]=period;

prevBatch=max(spl)
}
x
``````

## Efficiently process each unique permutation of a vector when number of unique elements in vector is much smaller than ve

By : Velocipede Berserker
Date : March 29 2020, 07:55 AM
Any of those help The permutations you have to work with are known in the field of combinatorics as multiset permutations.
They are described for example on The Combinatorial Object Server with more detailed explanations in this paper by professor Tadao Takaoka.
code :
``````// File:  MSetPermGen.h

#ifndef  MSET_PERM_GEN_H
#define  MSET_PERM_GEN_H

#include  <iostream>
#include  <vector>

class MSetPermGenImpl;  // from algorithmic backend

using  IntVec  = std::vector<int>;
using  SizeVec = std::vector<std::size_t>;

// Generator class for multiset permutations:

class MSetPermGen {
public:
MSetPermGen(const IntVec& vec);

std::size_t       getCycleLength() const;
bool              forward(size_t incr);
bool              next();
const SizeVec&    getPermIndices() const;
const IntVec&     getItems() const;
const IntVec&     getItemValues() const;

private:
std::size_t       cycleLength_;
MSetPermGenImpl*  genImpl_;         // implementation generator
IntVec            itemValues_;      // only once each
IntVec            items_;           // copy of ctor argument
SizeVec           freqs_;           // repetition counts
SizeVec           state_;           // array of indices in 0..n-1
};

#endif
``````
``````// File:  test_main.cpp

#include  <cassert>
#include  "MSetPermGen.h"

using  std::cout;
using  std::cerr;
using  std::endl;

// utility functions:

std::vector<int>  getMSPermutation(const MSetPermGen& mspg)
{
std::vector<int>  res;
auto indices = mspg.getPermIndices();  // always between 0 and n-1
auto values  = mspg.getItemValues();  // whatever the user put in

std::size_t n = indices.size();
assert( n == items.size() );
res.reserve(n);

for (std::size_t i=0; i < n; i++) {
auto xi = indices[i];
res.push_back(values[xi]);
}

return res;
}

void printPermutation(const std::vector<int>& p, std::ostream& fh)
{
std::size_t n = p.size();

for (size_t i=0; i < n; i++)
fh << p[i] << " ";
fh << '\n';
}

int main(int argc, const char* argv[])
{
std::vector<int>  vec0{1,1, 2,2,2};                        // N=5
std::vector<int>  vec1{1,1, 1,1, 2, 3, 2,2, 3,3, 1};       // N=11
std::vector<int>  vec2{1,1,1, 2,2,2, 3,3,3,3, 4,4,4,4,4};  // N=15

MSetPermGen  pg0{vec0};
MSetPermGen  pg1{vec1};
MSetPermGen  pg2{vec2};

auto pg = &pg0;  // choice of 0, 1, 2 for sizing
auto cl = pg->getCycleLength();

auto permA = getMSPermutation(*pg);
printPermutation(permA, cout);
for (std::size_t pi=0; pi < (cl-1); pi++) {
pg->next();
auto permB = getMSPermutation(*pg);
printPermutation(permB, cout);
}

return EXIT_SUCCESS;
}
``````
``````1 1 2 2 2
1 2 1 2 2
1 2 2 1 2
1 2 2 2 1
2 1 1 2 2
2 1 2 1 2
2 1 2 2 1
2 2 1 1 2
2 2 1 2 1
2 2 2 1 1
``````
``````// File:  MSetPermGen.cpp - part 1 of 2 - FXT code

// -------------- Beginning  of header-only FXT combinatorics code -----------

// This file is part of the FXT library.
// Copyright (C) 2010, 2012, 2014 Joerg Arndt
// see the file COPYING.txt in the main directory.

//--  https://www.jjj.de/fxt/
//--  https://fossies.org/dox/fxt-2018.07.03/mset-perm-lex_8h_source.html

#include  <cstddef>
using ulong = std::size_t;

inline void  swap2(ulong& xa, ulong& xb)
{
ulong  save_xb = xb;

xb = xa;
xa = save_xb;
}

class mset_perm_lex
// Multiset permutations in lexicographic order, iterative algorithm.
{
public:
ulong k_;    // number of different sorts of objects
ulong *r_;   // number of elements '0' in r[0], '1' in r[1], ..., 'k-1' in r[k-1]
ulong n_;    // number of objects
ulong *ms_;  // multiset data in ms[0], ..., ms[n-1], sentinels at [-1] and [-2]

private:  // have pointer data
mset_perm_lex(const mset_perm_lex&);  // forbidden
mset_perm_lex & operator = (const mset_perm_lex&);  // forbidden

public:
explicit mset_perm_lex(const ulong *r, ulong k)
{
k_ = k;
r_ = new ulong[k];
for (ulong j=0; j<k_; ++j)  r_[j] = r[j];  // get buckets

n_ = 0;
for (ulong j=0; j<k_; ++j)  n_ += r_[j];
ms_ = new ulong[n_+2];
ms_[0] = 0; ms_[1] = 1;  // sentinels:  ms[0] < ms[1]
ms_ += 2;  // nota bene

first();
}

void first()
{
for (ulong j=0, i=0;  j<k_;  ++j)
for (ulong h=r_[j];  h!=0;  --h, ++i)
ms_[i] = j;
}

~mset_perm_lex()
{
ms_ -= 2;
delete [] ms_;
delete [] r_;
}

const ulong * data()  const { return ms_; }

ulong next()
// Return position of leftmost change,
// return n with last permutation.
{
// find rightmost pair with ms[i] < ms[i+1]:
const ulong n1 = n_ - 1;
ulong i = n1;
do  { --i; }  while ( ms_[i] >= ms_[i+1] );  // can read sentinel
if ( (long)i < 0 )  return n_;  // last sequence is falling seq.

// find rightmost element ms[j] less than ms[i]:
ulong j = n1;
while ( ms_[i] >= ms_[j] )  { --j; }

swap2(ms_[i], ms_[j]);

// Here the elements ms[i+1], ..., ms[n-1] are a falling sequence.
// Reverse order to the right:
ulong r = n1;
ulong s = i + 1;
while ( r > s )  { swap2(ms_[r], ms_[s]);  --r;  ++s; }

return i;
}
};

// -------------- End of header-only FXT combinatorics code -----------
``````
``````// Second part of file MSetPermGen.cpp: non-FXT code

#include  <cassert>
#include  <tuple>
#include  <map>
#include  <iostream>
#include  <cstdio>

#include  "MSetPermGen.h"

using  std::cout;
using  std::cerr;
using  std::endl;

class MSetPermGenImpl {  // wrapper class
public:
MSetPermGenImpl(const SizeVec& freqs) : fg(freqs.data(), freqs.size())
{}
private:
mset_perm_lex   fg;

friend class MSetPermGen;
};

static std::size_t  fact(size_t n)
{
std::size_t  f = 1;

for (std::size_t i = 1; i <= n; i++)
f = f*i;
return f;
}

MSetPermGen::MSetPermGen(const IntVec& vec) : items_(vec)
{
std::map<int,int>  ma;

for (int i: vec) {
ma[i]++;
}
int item, freq;
for (const auto& p : ma) {
std::tie(item, freq) = p;
itemValues_.push_back(item);
freqs_.push_back(freq);
}
cycleLength_ = fact(items_.size());
for (auto i: freqs_)
cycleLength_ /= fact(i);

// create FXT-level generator:
genImpl_ = new MSetPermGenImpl(freqs_);
for (std::size_t i=0; i < items_.size(); i++)
state_.push_back(genImpl_->fg.ms_[i]);
}

std::size_t  MSetPermGen::getCycleLength() const
{
return cycleLength_;
}

bool  MSetPermGen::forward(size_t incr)
{
std::size_t  n  = items_.size();
std::size_t  rc = 0;

// move forward state by brute force, could be improved:
for (std::size_t i=0; i < incr; i++)
rc = genImpl_->fg.next();

for (std::size_t j=0; j < n; j++)
state_[j] = genImpl_->fg.ms_[j];
return (rc != n);
}

bool  MSetPermGen::next()
{
return forward(1);
}

const SizeVec&  MSetPermGen::getPermIndices() const
{
return (this->state_);
}

const IntVec&  MSetPermGen::getItems() const
{
return (this->items_);
}

const IntVec&  MSetPermGen::getItemValues() const
{
return (this->itemValues_);
}
``````
``````#include  <algorithm>
#include  <vector>
#include  <atomic>
#include  <mutex>
#include  <numeric>
#include  <set>
#include  <iostream>
#include  <fstream>
#include  <sstream>
#include  <cstdlib>

#include  "MSetPermGen.h"

using  std::cout;
using  std::endl;

// debug and instrumentation:
static std::atomic<size_t>  permCounter;
static bool doManagePermCounter = true;

template<class Container, class Func>
void parallel_for_each_permutation(const Container& container, int numThreads, Func mfunc) {

MSetPermGen  gen0(container);
std::size_t totalNumPermutations = gen0.getCycleLength();
std::size_t permShare = totalNumPermutations / numThreads;
if ((totalNumPermutations % numThreads) != 0)
permShare++;
std::cout << "totalNumPermutations: " << totalNumPermutations << std::endl;

// generate some per-thread logfile name
std::ostringstream  fnss;
fnss << "thrlog_" << threadId << ".txt";
std::string    fileName = fnss.str();
std::ofstream  fh(fileName);

MSetPermGen  thrGen(container);
const std::size_t firstPerm = permShare * threadId;
thrGen.forward(firstPerm);

const std::size_t last_excl = std::min(totalNumPermutations,

fh << "MSG firstPerm: " << firstPerm << '\n';
fh << "MSG lastExcl : " << last_excl << '\n';
}

Container permutation(container);
auto values      = thrGen.getItemValues();
auto permIndices = thrGen.getPermIndices();
auto nsz         = permIndices.size();

std::size_t count = firstPerm;
do {
for (std::size_t i = 0; i < nsz; i++) {
permutation[i] = values[permIndices[i]];
}

for (std::size_t i = 0; i < nsz; i++)
fh << permutation[i] << ' ';
fh << '\n';
}
thrGen.next();
permIndices = thrGen.getPermIndices();
++count;
if (doManagePermCounter) {
permCounter++;
}
} while (count < last_excl);

fh.close();
});
}

}

template<class Container, class Func>
void parallel_for_each_unique_permutation(const Container& container, Func func) {

parallel_for_each_permutation(
container,
// no longer need any mutual exclusion
func(permutation);
}
);
}

int main()
{
std::vector<int>  vector1{1,1,1,1,2,3,2,2,3,3,1};             // N=11
std::vector<int>  vector0{1,1, 2,2,2};                        // N=5
std::vector<int>  vector2{1,1,1, 2,2,2, 3,3,3,3, 4,4,4,4,4};  // N=15

auto func = [](const auto& vec) { return; };

permCounter.store(0);

parallel_for_each_unique_permutation(vector2, func);