Reputation: 2083
I am trying to transform a string by removing a letter A with an adjacent letter B or by removing a letter C toghether with an adjacent letter D.
For example 1, given a string "CBACD", it should be transformed as
CBACD -> CCD -> C
Example 2: given a string "CABABD", it should return nothing as the transformation goes like below:
CABABD -> CABD -> CD ->
Example 3: "ACBDACBD", There are no corresponding adjacent characters to A & C so the entire string should be returned
"ACBDACBD" -> "ACBDACBD"
I have written the following code to do the operation:
object RemoveCharsABCD {
val s = scala.io.StdIn
def adjacent(s: String): String = {
val charSet = ArrayBuffer("AB","BA","CD","DC")
var i = 0
var ret:String = ""
while(i < s.length-1) {
if(charSet.contains(s"${s.charAt(i)}${s.charAt(i+1)}")) {
s.slice(i+2, s.length)
i += 2
if(i == s.length-1) ret = s"$ret${s.charAt(i).toString}"
} else {
ret = s"$ret${s.charAt(i).toString}"
i += 1
if(i == s.length-1) ret = s"$ret${s.charAt(i).toString}"
}
}
println("Ret: " + ret)
ret
}
def main(args: Array[String]): Unit = {
println("Enter a String: ")
var s = scala.io.StdIn.readLine().toString
adjacent(s)
}
}
The above code works fine for the first iteration which is: CABABD -> CABD
For the inputs: ACBDACBD, CBACD, the output is correct but for ACBDACBD, the output is CD.
I called the method adjacent before the print statement as below:
if(ret.length >= 2) {
adjacent(ret)
}
println("Ret: " + ret)
But this goes to infinite loop and give stackoverflow
exception.
I am unable to call the method: adjacent
recursively so that it can work until the end of the string ?
Could anyone let me know how can I properly call the method: adjacent recursively so that the entire string is processed until the end ?
Upvotes: 4
Views: 3751
Reputation: 425
Python solution using stack:
def solution(S):
stack = []
for i, val in enumerate(S):
if stack and ((stack[-1] == "A" and val == "B") or (stack[-1] == "B" and val == "A") or
(stack[-1] == "C" and val == "D") or (stack[-1] == "D" and val == "C")):
stack.pop()
else:
stack.append(val)
return "".join(stack)
Upvotes: 0
Reputation: 2341
Here's a version in Kotlin:
fun solution(input: String): String {
val result = input.replace("AB|CD|DC|BA".toRegex(), "")
return if (result == input)
input
else
solution(result)
}
solution("CBACD") //output = C
solution("CABABD") //output =
solution("ACBDACBD") //output = ACBDACBD
Upvotes: 0
Reputation: 55
public static String solution(String str) {
String next = str.replaceAll("AB|CD|DC|BA", "");
if(str.equals(next))
return str;
else
return solution(next);
}
Upvotes: 0
Reputation: 9
private static String stringAfterRemove(String str,int val,int lengthOfString) {
String nStr = str.replaceAll("CD", "").replaceAll("DC", "").replaceAll("AB", "").replaceAll("BA", "");
if(val==lengthOfString)
return str;
return stringAfterRemove(nStr,++val,lengthOfString);
}
In main method, initialize int val =0.
Upvotes: 0
Reputation: 29
This could be done in Java, as follows :
public static String remove(String str)
{
if (str == null) {
return null;
}
char[] chars = str.toCharArray();
int i = 0, k = 0;
while (i < str.length())
{
if ( chars[i] == 'B' && (k > 0 && chars[k - 1] == 'A') ||
chars[i] == 'A' && (k > 0 && chars[k - 1] == 'B') ||
chars[i] == 'C' && (k > 0 && chars[k - 1] == 'D') ||
chars[i] == 'D' && (k > 0 && chars[k - 1] == 'C'))
{
--k;
++i;
}
else {
chars[k++] = chars[i++];
}
}
return new String(chars).substring(0, k);
}
Upvotes: 2
Reputation: 51271
Seems pretty straight forward.
@annotation.tailrec
def adjacent(s: String): String = {
val next = s.replaceAll("AB|BA|CD|DC", "")
if (s == next) s else adjacent(next)
}
adjacent("CBACD") //res0: String = C
adjacent("CABABD") //res1: String =
adjacent("ACBDACBD") //res2: String = ACBDACBD
Upvotes: 8