1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package Torello.Java;

import java.util.stream.IntStream;

class CharArrPrepend
{
    static String replace(
            final boolean   ignoreCase,
            final String    s,
            final char[]    matchCharsInput,
            final char      prependChar
        )
    {
        // Need a temporary 'count' variable
        int count = 0;

        // Improve the loop counter efficiency, use a 'len' instead of s.length()
        int len = s.length();

        final char[] matchChars;

        if (ignoreCase)
        {
            matchChars = new char[matchCharsInput.length];

            for (int i=0; i < matchChars.length; i++)
                matchChars[i] = Character.toLowerCase(matchCharsInput[i]);
        }

        else matchChars = matchCharsInput;


        // Use a Java Stream to save the locations of the matches
        IntStream.Builder whereB = IntStream.builder();

        // Count how many escape-characters are in the input-string
        if (ignoreCase)

            TOP1:
            for (int i=0; i < len; i++)
            {
                char c = Character.toLowerCase(s.charAt(i));

                // This checks if the character is a match with any of the match-characters in
                // the input array.

                for (char matchChar : matchChars)

                    if (matchChar == c)
                    {
                        whereB.accept(i);
                        continue TOP1;
                    }
            }

        else

            TOP2:
            for (int i=0; i < len; i++)
            {
                char c = s.charAt(i);

                // This checks if the character is a match with any of the match-characters in
                // the input array.

                for (char matchChar : matchChars)

                    if (matchChar == c)
                    {
                        whereB.accept(i);
                        continue TOP2;
                    }
            }


        // Build the java stream, and turn it into an index-pointer array (int array of
        // array indices)

        int[] whereArr = whereB.build().toArray();
    
        // No matches, return original string.
        if (whereArr.length == 0) return s;


        // The 'escaped string' will be longer than the original String by
        // 'whereArr.length' characters.  Use a character array to build this string

        char[] cArr = new char[len + whereArr.length];


        // There are now three different indices to keep up with - when doing this replace.
        // The input-string index.  The index of the "Match Locations Array" (whereArr), and the
        // index into the returned String - which, for now, is represented as a char[] array.

        int oldStrPos   = 0;
        int newStrPos   = 0;
        int i           = 0;

        while (oldStrPos < len)
        {
            // The next character in the input string
            char c = s.charAt(oldStrPos);

            // Was this one of the matches - as computed in the earlier loop?
            if (oldStrPos == whereArr[i])
            {
                // if "YES", then insert the prependChar, AND the original-string-char
                cArr[newStrPos++] = prependChar;
                cArr[newStrPos++] = c;


                // Here, increment the "Match Locations Array" index-location too.
                // (We have just "used up" one of the match-locations.

                i++;
            }
            else
                // if "NO", then just insert the original-string-char
                cArr[newStrPos++] = c;

            // Only at the end should we increment the input-string index-location.
            oldStrPos++;
        }

        // Convert the char array that was built into a String, and return it.
        return String.valueOf(cArr);
    }
}