Kaynağa Gözat

AK: Add String::find_all() and String::count()

Maciej Zygmanowski 4 yıl önce
ebeveyn
işleme
80077cea86
3 değiştirilmiş dosya ile 56 ekleme ve 6 silme
  1. 34 6
      AK/String.cpp
  2. 2 0
      AK/String.h
  3. 20 0
      Tests/AK/TestString.cpp

+ 34 - 6
AK/String.cpp

@@ -303,11 +303,8 @@ bool String::equals_ignoring_case(const StringView& other) const
     return StringUtils::equals_ignoring_case(view(), other);
     return StringUtils::equals_ignoring_case(view(), other);
 }
 }
 
 
-int String::replace(const String& needle, const String& replacement, bool all_occurrences)
+Vector<size_t> String::find_all(const String& needle) const
 {
 {
-    if (is_empty())
-        return 0;
-
     Vector<size_t> positions;
     Vector<size_t> positions;
     size_t start = 0, pos;
     size_t start = 0, pos;
     for (;;) {
     for (;;) {
@@ -317,11 +314,26 @@ int String::replace(const String& needle, const String& replacement, bool all_oc
 
 
         pos = ptr - characters();
         pos = ptr - characters();
         positions.append(pos);
         positions.append(pos);
-        if (!all_occurrences)
-            break;
 
 
         start = pos + 1;
         start = pos + 1;
     }
     }
+    return positions;
+}
+
+int String::replace(const String& needle, const String& replacement, bool all_occurrences)
+{
+    if (is_empty())
+        return 0;
+
+    Vector<size_t> positions;
+    if (all_occurrences) {
+        positions = find_all(needle);
+    } else {
+        auto pos = find(needle);
+        if (!pos.has_value())
+            return 0;
+        positions.append(pos.value());
+    }
 
 
     if (!positions.size())
     if (!positions.size())
         return 0;
         return 0;
@@ -338,6 +350,22 @@ int String::replace(const String& needle, const String& replacement, bool all_oc
     return positions.size();
     return positions.size();
 }
 }
 
 
+size_t String::count(const String& needle) const
+{
+    size_t count = 0;
+    size_t start = 0, pos;
+    for (;;) {
+        const char* ptr = strstr(characters() + start, needle.characters());
+        if (!ptr)
+            break;
+
+        pos = ptr - characters();
+        count++;
+        start = pos + 1;
+    }
+    return count;
+}
+
 String String::reverse() const
 String String::reverse() const
 {
 {
     StringBuilder reversed_string;
     StringBuilder reversed_string;

+ 2 - 0
AK/String.h

@@ -262,6 +262,8 @@ public:
     [[nodiscard]] StringView view() const;
     [[nodiscard]] StringView view() const;
 
 
     int replace(const String& needle, const String& replacement, bool all_occurrences = false);
     int replace(const String& needle, const String& replacement, bool all_occurrences = false);
+    size_t count(const String& needle) const;
+    Vector<size_t> find_all(const String& needle) const;
     [[nodiscard]] String reverse() const;
     [[nodiscard]] String reverse() const;
 
 
     template<typename T, typename... Rest>
     template<typename T, typename... Rest>

+ 20 - 0
Tests/AK/TestString.cpp

@@ -168,6 +168,26 @@ TEST_CASE(replace)
     EXPECT(test_string == "111._.|||._.|||");
     EXPECT(test_string == "111._.|||._.|||");
 }
 }
 
 
+TEST_CASE(count)
+{
+    String test_string = "Well, hello Friends!";
+    u32 count = test_string.count("Friends");
+    EXPECT(count == 1);
+
+    count = test_string.count("ell");
+    EXPECT(count == 2);
+
+    count = test_string.count("!");
+    EXPECT(count == 1);
+
+    test_string = String("111._.111._.111");
+    count = test_string.count("111");
+    EXPECT(count == 3);
+
+    count = test_string.count("._.");
+    EXPECT(count == 2);
+}
+
 TEST_CASE(substring)
 TEST_CASE(substring)
 {
 {
     String test = "abcdef";
     String test = "abcdef";