Process String with Special Operations I
Problem
Scan the string s from left to right, building a string result. A lowercase letter is appended to result. '*' removes the last character of result (if any). '#' duplicates result (appends it to itself). '%' reverses result. Return the final result.
s = "a#b%*""ba"def processStr(s):
result = [] # treat as a growable buffer
for ch in s:
if ch == '*': # remove last character
if result:
result.pop()
elif ch == '#': # duplicate the whole string
result = result + result
elif ch == '%': # reverse in place
result.reverse()
else: # lowercase letter: append
result.append(ch)
return ''.join(result)
function processStr(s) {
let result = []; // growable buffer
for (const ch of s) {
if (ch === '*') { // remove last character
if (result.length) result.pop();
} else if (ch === '#') { // duplicate the whole string
result = result.concat(result);
} else if (ch === '%') { // reverse in place
result.reverse();
} else { // lowercase letter: append
result.push(ch);
}
}
return result.join('');
}
String processStr(String s) {
StringBuilder result = new StringBuilder();
for (char ch : s.toCharArray()) {
if (ch == '*') { // remove last character
int n = result.length();
if (n > 0) result.deleteCharAt(n - 1);
} else if (ch == '#') { // duplicate the whole string
result.append(result);
} else if (ch == '%') { // reverse in place
result.reverse();
} else { // lowercase letter: append
result.append(ch);
}
}
return result.toString();
}
string processStr(string s) {
string result;
for (char ch : s) {
if (ch == '*') { // remove last character
if (!result.empty()) result.pop_back();
} else if (ch == '#') { // duplicate the whole string
result += result;
} else if (ch == '%') { // reverse in place
reverse(result.begin(), result.end());
} else { // lowercase letter: append
result += ch;
}
}
return result;
}
Explanation
This is a pure simulation: we replay each character of s in order and keep a single mutable buffer result. Whatever the current character says, we do to the buffer immediately.
A lowercase letter is the common case — just append it. The three special operators each rewrite the whole buffer: '*' pops the last character (and is a no-op when the buffer is already empty), '%' reverses the buffer, and '#' doubles it by concatenating the buffer with a copy of itself.
Order matters: because '#' appends the current contents to themselves, a duplicate captures everything built so far, so an early '#' can blow the string up quickly. With s.length ≤ 20 the buffer stays tiny, so the straightforward approach is plenty fast.
Walking the first example "a#b%*": append a → "a"; duplicate → "aa"; append b → "aab"; reverse → "baa"; pop → "ba". The answer is "ba".
Using a list / StringBuilder rather than rebuilding an immutable string on every step keeps the per-operation work proportional to the buffer length, which is all that is needed here.