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
target
string subject to removal - the
source
string 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
replaceAll
which 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).