Skip to main content
Code Review

Return to Question

Tweeted twitter.com/StackCodeReview/status/1104668370622922752
replaced http://codereview.stackexchange.com/ with https://codereview.stackexchange.com/
Source Link

Adding another level to my previous question previous question on 'normal' palindrome identification, in this one I'm interested in identifying genetic palindromes. Here's my attempt:

Adding another level to my previous question on 'normal' palindrome identification, in this one I'm interested in identifying genetic palindromes. Here's my attempt:

Adding another level to my previous question on 'normal' palindrome identification, in this one I'm interested in identifying genetic palindromes. Here's my attempt:

rc_table -> complement_table
Source Link
Daniel
  • 825
  • 2
  • 8
  • 15
#include <iterator>
#include <algorithm>
#include <array>
namespace detail
{
 static constexpr std::array<char, 128> rc_tablecomplement_table
 {
 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 84, 4, 71, 4, 4, 4, 67, 4, 4, 4, 4, 4, 4, 78, 4,
 4, 4, 4, 4, 65, 65, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 84, 4, 71, 4, 4, 4, 67, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 4, 4, 4, 65, 65, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
 };
} // namespace detail
inline constexpr char complement(const char base)
{
 return detail::rc_table[base];complement_table[base];
}
namespace detail
{
 template <typename RandomIt>
 bool is_palindromic(RandomIt first, RandomIt last, std::random_access_iterator_tag)
 {
 if (first == last) return true;
 
 const auto size = std::distance(first, last);
 
 if (size % 2 != 0) return false;
 
 return std::equal(first, std::next(first, size / 2), std::make_reverse_iterator(last),
 [] (const char lhs, const char rhs) {
 return lhs == complement(rhs);
 });
 }
 template <typename BidirIt>
 bool is_palindromic(BidirIt first, BidirIt last, std::bidirectional_iterator_tag)
 {
 if (first == last) return true;
 if (first == --last) return false;
 
 for (; first != last; ++first, --last) {
 if (*first != complement(*last)) return false;
 if (std::next(first) == last) return true;
 }
 
 return false;
 }
} // namespace detail
template <typename BidirIt>
bool is_palindromic(BidirIt first, BidirIt last)
{
 return detail::is_palindromic(first, last, typename std::iterator_traits<BidirIt>::iterator_category {});
}
template <typename SequenceType>
bool is_palindromic(const SequenceType& sequence)
{
 return is_palindromic(std::cbegin(sequence), std::cend(sequence));
}
#include <iterator>
#include <algorithm>
#include <array>
namespace detail
{
 static constexpr std::array<char, 128> rc_table
 {
 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 84, 4, 71, 4, 4, 4, 67, 4, 4, 4, 4, 4, 4, 78, 4,
 4, 4, 4, 4, 65, 65, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 84, 4, 71, 4, 4, 4, 67, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 4, 4, 4, 65, 65, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
 };
} // namespace detail
inline constexpr char complement(const char base)
{
 return detail::rc_table[base];
}
namespace detail
{
 template <typename RandomIt>
 bool is_palindromic(RandomIt first, RandomIt last, std::random_access_iterator_tag)
 {
 if (first == last) return true;
 
 const auto size = std::distance(first, last);
 
 if (size % 2 != 0) return false;
 
 return std::equal(first, std::next(first, size / 2), std::make_reverse_iterator(last),
 [] (const char lhs, const char rhs) {
 return lhs == complement(rhs);
 });
 }
 template <typename BidirIt>
 bool is_palindromic(BidirIt first, BidirIt last, std::bidirectional_iterator_tag)
 {
 if (first == last) return true;
 if (first == --last) return false;
 
 for (; first != last; ++first, --last) {
 if (*first != complement(*last)) return false;
 if (std::next(first) == last) return true;
 }
 
 return false;
 }
} // namespace detail
template <typename BidirIt>
bool is_palindromic(BidirIt first, BidirIt last)
{
 return detail::is_palindromic(first, last, typename std::iterator_traits<BidirIt>::iterator_category {});
}
template <typename SequenceType>
bool is_palindromic(const SequenceType& sequence)
{
 return is_palindromic(std::cbegin(sequence), std::cend(sequence));
}
#include <iterator>
#include <algorithm>
#include <array>
namespace detail
{
 static constexpr std::array<char, 128> complement_table
 {
 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 84, 4, 71, 4, 4, 4, 67, 4, 4, 4, 4, 4, 4, 78, 4,
 4, 4, 4, 4, 65, 65, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 84, 4, 71, 4, 4, 4, 67, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 4, 4, 4, 65, 65, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
 };
} // namespace detail
inline constexpr char complement(const char base)
{
 return detail::complement_table[base];
}
namespace detail
{
 template <typename RandomIt>
 bool is_palindromic(RandomIt first, RandomIt last, std::random_access_iterator_tag)
 {
 if (first == last) return true;
 
 const auto size = std::distance(first, last);
 
 if (size % 2 != 0) return false;
 
 return std::equal(first, std::next(first, size / 2), std::make_reverse_iterator(last),
 [] (const char lhs, const char rhs) {
 return lhs == complement(rhs);
 });
 }
 template <typename BidirIt>
 bool is_palindromic(BidirIt first, BidirIt last, std::bidirectional_iterator_tag)
 {
 if (first == last) return true;
 if (first == --last) return false;
 
 for (; first != last; ++first, --last) {
 if (*first != complement(*last)) return false;
 if (std::next(first) == last) return true;
 }
 
 return false;
 }
} // namespace detail
template <typename BidirIt>
bool is_palindromic(BidirIt first, BidirIt last)
{
 return detail::is_palindromic(first, last, typename std::iterator_traits<BidirIt>::iterator_category {});
}
template <typename SequenceType>
bool is_palindromic(const SequenceType& sequence)
{
 return is_palindromic(std::cbegin(sequence), std::cend(sequence));
}
Source Link
Daniel
  • 825
  • 2
  • 8
  • 15

Determining if a genetic sequence is palindromic

Adding another level to my previous question on 'normal' palindrome identification, in this one I'm interested in identifying genetic palindromes. Here's my attempt:

#include <iterator>
#include <algorithm>
#include <array>
namespace detail
{
 static constexpr std::array<char, 128> rc_table
 {
 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 84, 4, 71, 4, 4, 4, 67, 4, 4, 4, 4, 4, 4, 78, 4,
 4, 4, 4, 4, 65, 65, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 84, 4, 71, 4, 4, 4, 67, 4, 4, 4, 4, 4, 4, 4, 4,
 4, 4, 4, 4, 65, 65, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
 };
} // namespace detail
inline constexpr char complement(const char base)
{
 return detail::rc_table[base];
}
namespace detail
{
 template <typename RandomIt>
 bool is_palindromic(RandomIt first, RandomIt last, std::random_access_iterator_tag)
 {
 if (first == last) return true;
 
 const auto size = std::distance(first, last);
 
 if (size % 2 != 0) return false;
 
 return std::equal(first, std::next(first, size / 2), std::make_reverse_iterator(last),
 [] (const char lhs, const char rhs) {
 return lhs == complement(rhs);
 });
 }
 template <typename BidirIt>
 bool is_palindromic(BidirIt first, BidirIt last, std::bidirectional_iterator_tag)
 {
 if (first == last) return true;
 if (first == --last) return false;
 
 for (; first != last; ++first, --last) {
 if (*first != complement(*last)) return false;
 if (std::next(first) == last) return true;
 }
 
 return false;
 }
} // namespace detail
template <typename BidirIt>
bool is_palindromic(BidirIt first, BidirIt last)
{
 return detail::is_palindromic(first, last, typename std::iterator_traits<BidirIt>::iterator_category {});
}
template <typename SequenceType>
bool is_palindromic(const SequenceType& sequence)
{
 return is_palindromic(std::cbegin(sequence), std::cend(sequence));
}

Used as such:

#include <iostream>
#include <string>
#include <list>
int main()
{
 std::cout << std::boolalpha;
 std::string str {"ACCTAGGT"};
 std::cout << is_palindromic(str) << std::endl;
 std::list<char> lst {str.cbegin(), str.cend()};
 std::cout << is_palindromic(lst) << std::endl;
 return 0;
}

Performance is my primary concern here. Comments and suggested improvements are welcome!

lang-cpp

AltStyle によって変換されたページ (->オリジナル) /