Skip to content

Commit 861e82c

Browse files
committed
#73 - Refactor method CppStringT::rsplit()
Completed.
1 parent b235aef commit 861e82c

File tree

1 file changed

+90
-35
lines changed

1 file changed

+90
-35
lines changed

cpp-strings/cppstrings.h

Lines changed: 90 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <cwctype>
2727
#include <format>
2828
#include <map>
29+
#include <ranges>
2930
#include <span>
3031
#include <stdexcept>
3132
#include <string_view>
@@ -106,7 +107,8 @@ namespace pcs // i.e. "pythonic c++ strings"
106107
{
107108
public:
108109
//=== Wrappers ========================================
109-
using MyBaseClass = std::basic_string<CharT>;
110+
using MyBaseClass = std::basic_string<CharT>;
111+
using MyStringView = std::basic_string_view<CharT>;
110112

111113
using traits_type = MyBaseClass::traits_type;
112114
using value_type = MyBaseClass::value_type;
@@ -141,6 +143,7 @@ namespace pcs // i.e. "pythonic c++ strings"
141143

142144
template<class StringViewLike>
143145
explicit CppStringT(const StringViewLike& svl) : MyBaseClass(svl) {}
146+
144147
template<class StringViewLike>
145148
CppStringT(const StringViewLike& svl, size_type pos, size_type n) : MyBaseClass(svl, pos, n) {}
146149

@@ -888,7 +891,7 @@ namespace pcs // i.e. "pythonic c++ strings"
888891

889892

890893
//--- rpartition() -------------------------------------
891-
/** Split the string at the last occurrence of sep, and returns a 3-items vector containing the part before the separator, the separator itself, and the part after the separator.
894+
/** Splits the string at the last occurrence of sep, and returns a 3-items vector containing the part before the separator, the separator itself, and the part after the separator.
892895
*
893896
* If the separator is not found, returns a 3-items vector
894897
* containing the string itself, followed by two empty strings.
@@ -909,67 +912,119 @@ namespace pcs // i.e. "pythonic c++ strings"
909912

910913

911914
//--- rsplit() ----------------------------------------
912-
/** \brief Returns a vector of the words in the string, as seperated with whitespace strings. */
915+
/** \brief Returns a vector of the words in the whole string, as seperated with whitespace strings. */
913916
inline std::vector<CppStringT> rsplit() const noexcept
914917
{
915918
return split();
916919
}
917920

918-
/** \brief Returns a vector of the words in the string, using sep as the delimiter string. */
921+
/** \brief Returns a vector of the words in the whole string, using sep as the delimiter string. */
919922
inline std::vector<CppStringT> rsplit(const CppStringT& sep) const noexcept
920923
{
921924
return split(sep);
922925
}
923926

924-
/** \brief Returns a vector of the words in the string, as seperated with whitespace strings.
925-
*
926-
* At most maxsplit splits are done, the rightmost ones.
927-
*/
927+
/** \brief Returns a vector of the words in the string, as seperated with whitespace strings. At most maxsplit splits are done, the rightmost ones. */
928928
std::vector<CppStringT> rsplit(const size_type maxsplit) const noexcept
929929
{
930-
if (maxsplit == 0)
931-
return *this;
930+
std::vector<CppStringT> res{};
932931

933-
constexpr CppStringT spc2(" ");
934-
constexpr CppStringT spc(value_type(' '));
935-
CppStringT tmp = *this;
936-
while (tmp.contains(spc2))
937-
tmp = tmp.replace(spc2, spc);
932+
if (maxsplit == 0) {
933+
res.push_back(*this);
934+
}
935+
else {
936+
const CppStringT whitespace(value_type(' '));
937+
std::vector<CppStringT> all_words{ this->split(whitespace) };
938+
939+
size_type count = maxsplit;
940+
auto word_it = all_words.crbegin();
941+
size_type last_split_index = all_words.size();
942+
while (count > 0 && word_it != all_words.crend()) {
943+
if (!word_it->empty()) {
944+
res.insert(res.cbegin(), *word_it);
945+
--count;
946+
--last_split_index;
947+
}
948+
word_it++;
949+
}
950+
951+
size_type chars_count = last_split_index;
952+
while (last_split_index > 0) {
953+
chars_count += all_words[last_split_index].size();
954+
--last_split_index;
955+
}
956+
if (chars_count > 0)
957+
res.insert(res.cbegin(), this->substr(0, chars_count));
958+
/*
959+
constexpr CppStringT spc2(" ");
960+
constexpr CppStringT spc(value_type(' '));
961+
CppStringT tmp = *this;
962+
while (tmp.contains(spc2))
963+
tmp = tmp.replace(spc2, spc);
964+
965+
res = tmp->rsplit(spc, maxsplit);
966+
*/
967+
}
938968

939-
return this->rsplit(spc, maxsplit);
969+
return res;
940970
}
941971

942972
/** \brief Returns a vector of the words in the string, using sep as the delimiter string.
943973
*
944-
* At most maxsplit splits are done, the rightmost ones. Except
945-
* for splitting from the right, rsplit() behaves like split()].
974+
* At most maxsplit splits are done, the rightmost ones.
946975
*/
947976
std::vector<CppStringT> rsplit(const CppStringT& sep, const size_type maxsplit) const noexcept
948977
{
949978
std::vector<CppStringT> res{};
950979

951-
std::vector<CppStringT> indexes{};
952-
CppStringT tmp = *this;
953-
size_type count = maxsplit;
954-
size_type index;
955-
while ((index = tmp.rfind(sep)) != CppStringT::npos && count > 0) {
956-
indexes.insert(indexes.begin(), index);
957-
if (index == 0)
958-
break;
959-
tmp = tmp.substr(0, index-1);
960-
count--;
980+
if (maxsplit == 0) {
981+
res.push_back({ *this });
961982
}
962-
963-
if (indexes.size() == 0)
964-
res.push_back(*this);
965983
else {
966-
index = 0;
967-
for (const size_type ndx: indexes) {
968-
res.push_back(this->substr(index, ndx - index));
969-
index = ndx + 1;
984+
std::vector<CppStringT> all_words{ this->split(sep) };
985+
986+
size_type count = maxsplit;
987+
auto word_it = all_words.crbegin();
988+
size_type last_split_index = all_words.size();
989+
while (count > 0 && word_it != all_words.crend()) {
990+
res.insert(res.cbegin(), *word_it);
991+
--count;
992+
--last_split_index;
993+
word_it++;
994+
}
995+
996+
size_type chars_count = last_split_index;
997+
while (last_split_index > 0) {
998+
chars_count += all_words[last_split_index].size();
999+
--last_split_index;
1000+
}
1001+
if (chars_count > 0)
1002+
res.insert(res.cbegin(), this->substr(0, chars_count));
1003+
/*
1004+
std::vector<CppStringT> indexes{};
1005+
CppStringT tmp = *this;
1006+
size_type count = maxsplit;
1007+
size_type index;
1008+
while ((index = tmp.rfind(sep)) != CppStringT::npos && count > 0) {
1009+
indexes.insert(indexes.begin(), index);
1010+
if (index == 0)
1011+
break;
1012+
tmp = tmp.substr(0, index-1);
1013+
count--;
1014+
}
1015+
1016+
if (indexes.size() == 0)
1017+
res.push_back(*this);
1018+
else {
1019+
index = 0;
1020+
for (const size_type ndx: indexes) {
1021+
res.push_back(this->substr(index, ndx - index));
1022+
index = ndx + 1;
9701023
}
9711024
res.push_back(this->substr(index, this->size() - index));
1025+
*/
9721026
}
1027+
9731028
return res;
9741029
}
9751030

0 commit comments

Comments
 (0)