std::is_permutation to isnot_permutation

Mar 17, 2021 at 9:02pm
I'm in need of the opposite of is_permutation. So I looked at the c++ reference and saw this in regards to is_permutation.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template <class InputIterator1, class InputIterator2>
  bool is_permutation (InputIterator1 first1, InputIterator1 last1,
                       InputIterator2 first2)
{
  std::tie (first1,first2) = std::mismatch (first1,last1,first2);
  if (first1==last1) return true;
  InputIterator2 last2 = first2; std::advance (last2,std::distance(first1,last1));
  for (InputIterator1 it1=first1; it1!=last1; ++it1) {
    if (std::find(first1,it1,*it1)==it1) {
      auto n = std::count (first2,last2,*it1);
      if (n==0 || std::count (it1,last1,*it1)!=n) return false;
    }
  }
  return true;
}

In one of my earlier topics, keskiverto created a custom template for me that worked perfectly!! So, I thought that maybe if I made some changes, I could create isnot_permutation. I was very aprehensive to try this without knowing what I was doing. I thought that maybe if I change the name and the return bools that maybe it would work. First I just changed the last return bool and it didn't workout. Then I changed all the bool values and it seemed to work ok. Not enough testing done yet. But can more expoerienced people check this idea out. I have absolutely no knowledge on doing something like this. Am I on the verge of creating potentially more problems? I just thought I would give it a try. Like I said, I haven't done much testing yet, but checkout the template that I modified. Is it ok?? Heck, I don't even understand what some of it means YET. Here is what I did:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template <class InputIterator1, class InputIterator2>
  bool isnot_permutation (InputIterator1 first1, InputIterator1 last1,
                       InputIterator2 first2)
{
  std::tie (first1,first2) = std::mismatch (first1,last1,first2);
  if (first1==last1) return false;
  InputIterator2 last2 = first2; std::advance (last2,std::distance(first1,last1));
  for (InputIterator1 it1=first1; it1!=last1; ++it1) {
    if (std::find(first1,it1,*it1)==it1) {
      auto n = std::count (first2,last2,*it1);
      if (n==0 || std::count (it1,last1,*it1)!=n) return true;
    }
  }
  return false;
}
Last edited on Mar 17, 2021 at 9:03pm
Mar 17, 2021 at 9:14pm
If the former works the latter must necessarily work. You did the equivalent of
1
2
3
4
5
6
template <class InputIterator1, class InputIterator2>
  bool isnot_permutation (InputIterator1 first1, InputIterator1 last1,
                       InputIterator2 first2)
{
    return !std::is_permutation(first1, last1, first2);
}
Mar 17, 2021 at 9:19pm
Your way looks a lot better and less code. So what you are saying is I could have done just that? Just learning here, this is all new to me.
Mar 17, 2021 at 10:10pm
Well, yes.
(x is not a permutation of y) ==
!(x is a permutation of y) ==
!std::is_permutation(x.begin(), x.end(), y.begin())
Mar 18, 2021 at 1:13am
THANKS!!! Appreciate it!
Brian
Topic archived. No new replies allowed.