Okay been on this for a while now and have gone through many different versions of doing this the goal is to have a method like remove("pdi") and it will return "eter er cke"
public class CodioCustomString {
public static void main(String[] args) {
System.out.println(remove("pdi"));
}
//2 Variables
static String myString = "peter piper picked";
boolean isSet;
//constructor
public static String remove(String arg) {
char[] chars = arg.toCharArray();
StringBuilder newString = new StringBuilder(myString);
for(char i: chars) {
for(int k = 0; k < myString.length(); k ) {
if(i == myString.charAt(k)) {
newString.deleteCharAt(k);
continue;
}
else {
continue;
}
}
}
return newString.toString();
}
CodePudding user response:
Here are three methods to do it. The methods take two argument.
- the
targetstring subject to removal - the
sourcestring of characters to be removed.
String result1 = remove1("peter piper picked", "pbi");
System.out.println(result1);
String result2 = remove2("peter piper picked", "pbi");
System.out.println(result2);
String result3 = remove3("peter piper picked", "pbi");
System.out.println(result3);
prints
eter er cked
eter er cked
eter er cked
Explanations
remove1
The easiest way is as follows:
- use
replaceAllwhich takes a regular expression [abc]is a character class which matches any of those characters. So simply create one by surrounding your letters to be removed with brackets.- replace the occurrence of those characters with an empty string.
public static String remove1(String target, String toBeRemoved) {
return target.replaceAll("[" toBeRemoved "]", "");
}
remove2
If you prefer to do it in a loop you can do the following:
- simply iterate across the characters of the string.
- if the removal letters contains the character, ignore it.
- else append it to a
StringBuilder
public static String remove2(String target, String toBeRemoved) {
StringBuilder sb = new StringBuilder();
for (char ch : target.toCharArray()) {
if (!toBeRemoved.contains(Character.toString(ch))) {
sb.append(ch);
}
}
return sb.toString();
}
remove3
This method streams the characters.
- map each character to a string
- filter out the ones to be removed
- collect into a new String using
Collectors.joining()
public static String remove3(String target, String toBeRemoved) {
return target.chars().mapToObj(Character::toString)
.filter(s->!toBeRemoved.contains(s))
.collect(Collectors.joining());
}
CodePudding user response:
The problem is that you are comparing the length of myString in the for loop which is fixed. Instead you should be comparing it with the length of StringBuilder ( newString in this case) as you are reducing the length when performing the delete operation.
Also, the time complexity (t.c) of the above code is O(n*k) where n is the length of the string and k the length of string that needs to be removed.
You can improve the time complexity by storing the character in a set and then iterating the newString and performing the remove operation.
public class CodioCustomString {
public static void main(String[] args) {
System.out.println(remove("pdi"));
System.out.println(remove2("pdi"));
}
// 2 Variables
static String myString = "peter piper picked";
boolean isSet;
/** tc - o(nk) where k is length of args string and n is length of string */
private static String remove(String arg) {
char[] chars = arg.toCharArray();
StringBuilder newString = new StringBuilder(myString);
for (char i : chars) {
for (int k = 0; k < newString.length(); k ) {
if (i == newString.charAt(k)) {
newString.deleteCharAt(k);
k--;
} else {
continue;
}
}
}
return newString.toString();
}
/**
* tc - o(n) o(k) where k is length of args string and n is length of string
*/
private static String remove2(String arg) {
char[] chars = arg.toCharArray();
Set<Character> set = new HashSet<>();
for (char i : chars) {
set.add(i);
}
StringBuilder newString = new StringBuilder(myString);
for (int k = 0; k < newString.length(); k ) {
if (set.contains(newString.charAt(k))) { // set.contains is o(1) operations
newString.deleteCharAt(k);
k--;
}
}
return newString.toString();
}
}
and the expected output :
eter er cke
eter er cke
CodePudding user response:
After the first delete in StringBuilder, it’s not consistent with myString. So, you are not exactly removing the same character you are referring in myString. To fix, iterate on newString instead of myString.
Better solution with lower time complexity:
import java.util.*;
import java.util.stream.*;
class Main {
static String myString = "peter piper picked";
public static void main(String args[]) {
System.out.println(remove("pdi"));
}
public static String remove(String arg) {
Set<Character> set = arg.chars()
.mapToObj(c -> (char) c)
.collect(Collectors.toSet());
StringBuilder sb = new StringBuilder();
for(int i = 0; i < myString.length(); i ) {
if (!set.contains(myString.charAt(i))) {
sb.append(myString.charAt(i));
}
}
/*
OR:
myString.chars()
.mapToObj(c -> (char) c)
.filter(c -> !set.contains(c))
.forEach(sb::append);
*/
return sb.toString();
}
}
Using a set for the argument String will save you one loop and the operation can be O(n) instead of O(nk).
