how can I modify my code so that it removes all the characters in a given string (not just a string) in another string in O(n)? If using other data structures would help, please hint as well.
public static String removeChar(String s, char ch){
StringBuilder sb= new StringBuilder();
char[] charArray= s.toCharArray();
for (int i=0; i<charArray.length; i++){
if (charArray[i]!=ch) {
sb.append(charArray[i]);
}
}
return sb.toString();
}
Is there a faster way for this?
UPDATE: I want to write a new function like removeAllCharsInSecondStringFromFirstString(String S1, String S2)
Rather then iterating each character of the String, you could use String.indexOf(int) and a loop to add each substring between ch intervals. Something like,
public static String removeChar(String s, char ch) {
StringBuilder sb = new StringBuilder();
int p1 = 0, p2 = s.indexOf(ch);
while (p2 > -1) {
sb.append(s.substring(p1, p2));
p1 = p2 + 1;
p2 = s.indexOf(ch, p1);
}
if (p1 < s.length()) {
sb.append(s.substring(p1, s.length()));
}
return sb.toString();
}
With hints and help of dimo I wrote this solution:
public static String removeAllChars(String src, String dst){
HashSet<Character> chars = new HashSet<>();
char[] dstCharArray=dst.toCharArray();
for (int i=0; i<dstCharArray.length; i++){
chars.add(dstCharArray[i]);
}
StringBuilder sb = new StringBuilder();
char[] srcCharArray = src.toCharArray();
for (int i=0; i<srcCharArray.length; i++){
if (!chars.contains(srcCharArray[i])){
sb.append(srcCharArray[i]);
}
}
return sb.toString();
}
If you really want to implement this yourself you can use a Set to contain the collection of characters that you want to strip out. Here's a template to get you started:
public static String removeAllChars(String source, String charsString) {
HashSet<Character> chars = new HashSet<>();
for (int i = 0; i < charsString.length(); i++) {
chars.add(charsString.charAt(i));
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < source.length(); i++) {
// chars.contains(source.charAt(i)) is O(1)
// use this to determine which chars to exclude
}
return sb.toString();
}
Try to use this.
Remove all no numerical value
String str = "343.dfsdgdffsggdfg333";
str = str.replaceAll("[^\\d.]", "");
Output will give you "343.333"
If in the future you will need delete numerical and special value try this
String str = "343.dfsdgdffsggdfg333";
string = string.replace(/[^a-zA-Z0-9]/g, '');
Related
I am currently implementing Run Length Encoding for text compression and my algorithm does return Strings of the following form:
Let's say we have a string as input
"AAAAABBBBCCCCCCCC"
then my algorithm returns
"1A2A3A4A5A1B2B3B4B1C2C3C4C5C6C7C8C"
Now I want to apply Java String split to solve this, because I want to get the highest number corresponding to character. For our example it would be
"5A4B8C"
My function can be seen below
public String getStrfinal(){
String result = "";
int counter = 1;
StringBuilder sb = new StringBuilder();
sb.append("");
for (int i=0;i<str.length()-1;i++) {
char c = str.charAt(i);
if (str.charAt(i)==str.charAt(i+1)) {
counter++;
sb.append(counter);
sb.append(c);
}
else {
counter = 1;
continue;
}
}
result = sb.toString();
return result;
}
public static String getStrfinal(){
StringBuilder sb = new StringBuilder();
char last = 0;
int count = 0;
for(int i = 0; i < str.length(); i++) {
if(i > 0 && last != str.charAt(i)) {
sb.append(count + "" + last);
last = 0;
count = 1;
}
else {
count++;
}
last = str.charAt(i);
}
sb.append(count + "" + last);
return sb.toString();
}
Here is one possible solution. It starts with the raw string and simply iterates thru the string.
public static void main(String[] args) {
String input = "AAAABBBCCCCCCCDDDEAAFBBCD";
int index = 0;
StringBuilder sb = new StringBuilder();
while (index < input.length()) {
int count = 0;
char c = input.charAt(index);
for (; index < input.length(); index++) {
if (c != input.charAt(index)) {
count++;
}
else {
break;
}
}
sb.append(Integer.toString(count));
sb.append(c);
count = 0;
}
System.out.println(sb.toString());
}
But one problem with this method and others is what happens if there are digits in the text? For example. What if the string is AAABB999222AAA which would compress to 3A2B39323A. That could also mean AAABB followed by 39 3's and 23 A's
Instead of string Buffer you can use a map it will be much easier and clean to do so.
public static void main(String[] args) {
String input = "AAAAABBBBCCCCCCCCAAABBBDDCCCC";
int counter=1;
for(int i=1; i<input.length(); i++) {
if(input.charAt(i-1)==input.charAt(i)) {
counter=counter+1;
}else if(input.charAt(i-1)!=input.charAt(i)){
System.out.print(counter+Character.toString(input.charAt(i-1)));
counter=1;
}if(i==input.length()-1){
System.out.print(counter+Character.toString(input.charAt(i)));
}
}
}
This will gives
5A4B8C3A3B2D4C
UPDATES
I Agree with #WJS if the string contains number the out put becomes messy
hence if the System.out in above code will be exchange with below i.e.
System.out.print(Character.toString(input.charAt(i-1))+"="+counter+" ");
then for input like
AAAAABBBBCCCCCCCCAAABBBDD556677CCCCz
we get out put as below
A=5 B=4 C=8 A=3 B=3 D=2 5=2 6=2 7=2 C=4 z=1
This is one of the possible solutions to your question. We can use a LinkedHashMap data structure which is similar to HashMap but it also maintains the order. So, we can traverse the string and store the occurrence of each character as Key-value pair into the map and retrieve easily with its maximum occurrence.
public String getStrFinal(String str){
if(str==null || str.length()==0) return str;
LinkedHashMap<Character,Integer> map = new LinkedHashMap<>();
StringBuilder sb=new StringBuilder(); // to store the final string
for(char ch:str.toCharArray()){
map.put(ch,map.getOrDefault(ch,0)+1); // put the count for each character
}
for(Map.Entry<Character,Integer> entry:map.entrySet()){ // iterate the map again and append each character's occurence into stringbuilder
sb.append(entry.getValue());
sb.append(entry.getKey());
}
System.out.println("String = " + sb.toString()); // here you go, we got the final string
return sb.toString();
}
How to create a String in Java by adding char by char.
I have to do it like this, because i have to add a "," between al letters.
I tried it like this, but it had not worked.
String t;
int l = t.length();
char[] a;
a = new char[l];
String rel = ",";
String ret = null;
for (int i = 0; i<l; i++){
a[i] = new Character(t.charAt(0));
}
for (int v = 0; v<l; v--){
ret += a[v];
ret += rel;
}
You don't need to do it so complicated, and you should explicitly use StringBuilder for such string operations:
String s = "abcdefg";
StringBuilder builder = new StringBuilder();
for (char c : s.toCharArray()) {
builder.append(c).append(",");
}
// Alternatively, you can do it in this way
for (String symbol : s.split("")) {
builder.append(symbol).append(",");
}
System.out.println(builder.toString());
// Java 8 (the result string doesn't have a comma at the end)
String collect = Arrays.stream(s.split("")).collect(Collectors.joining(","));
// Java8 StringJoiner
StringJoiner sj = new StringJoiner(",");
// StringJoiner sj = new StringJoiner(",", "", ",");
for (String str : s.split("")) {
sj.add(str);
}
If you use empty strings instead of null and initialize it then it works.
String t = "foobarbaz";
int l = t.length();
char[] a;
a = new char[l];
String rel = ",";
String ret = "";
for (int i = 0; i<l; i++){
a[i] = t.charAt(i);
}
for (int v = 0; v<l; v++){
ret += a[v];
ret += rel;
}
System.out.println(ret);
I've put the errors in your code in comments.
String t;
int l = t.length();
char[] a;
a = new char[l];
String rel = ",";
String ret = null; //you initialize ret to null, it should be "";
for (int i = 0; i<l; i++){
//you always set it to the character at position 0, you should do t.charAt(i)
//you don't need to use the wrapper class just t.charAt(i) will be fine.
a[i] = new Character(t.charAt(0));
}
for (int v = 0; v<l; v--){//you decrement v instead of incrementing it, this will lead to exceptions
ret += a[v];
ret += rel;//you always add the delimiter, note that this will lead to a trailing delimiter at the end
}
You might want to try a StringBuilder. It's a lot more efficient than using string concatenation. Using the array a is also not really necessary. Have a look at this implementation.
String t = "Test";
StringBuilder builder = new StringBuilder();
if(t.length() > 0){
builder.append(t.charAt(0));
for(int i=1;i<t.length();i++){
builder.append(",");
builder.append(t.charAt(i));
}
}
System.out.println(builder.toString());
Take a look at this:
//Word to be delimited by commas
String t = "ThisIsATest";
//get length of word.
int l = t.length(); //4
char[] a;
a = new char[l];
// we will set this to a comma below inside the loop
String rel = "";
//set ret to empty string instead of null otherwise the word "null" gets put at the front of your return string
String ret = "";
for (int i = 0; i<l; i++){
//you had 0 instead of 'i' as the parameter of t.charAt. You need to iterate through the elements of the string as well
a[i] = new Character(t.charAt(i));
}
for (int v = 0; v<l; v++){
/*set rel to empty string so that you can add it BEFORE the first element of the array and then afterwards change it to a comma
this prevents you from having an extra comma at the end of your list. */
ret += rel;
ret += a[v];
rel = ",";
}
System.out.println(ret);
String text = "mydata";
char[] arrayText = text.toCharArray();
char[] arrayNew = new char[arrayText.length*2];
for(int i = 0, j = 0; i < arrayText.length; i++, j+=2){
arrayNew[j] = arrayText[i];
arrayNew[j+1] = ',';
}
String stringArray = new String(arrayNew);
System.out.println(stringArray);
Results
m,y,d,a,t,a,
I have big string array and on every index I have a letter. I need to make a recall from this array and compose all this letters to one word/string. How would I do that in java?
String[] letters;
int lettersToRecall =16;
String word;
for(int i=0; i<lettersToRecall; i++){
//accumm letters into String Word..
}
This most straightforward method is to add all strings together:
String word = "";
for(int i = 0; i < lettersToRecall; i++){
word += letters[i];
}
This method (simply adding String objects) wastes lots of String instances as each addition result in a new instance.
So, if you are concerned with resource usage you could use StringBuilder instead:
StringBuilder builder = new StringBuilder();
for(int i = 0; i < lettersToRecall; i++){
builder.append(letters[i]);
}
String word = builder.toString();
For more information check when to use StringBuilder in java
String letters="your string here";
String result="";
for(int i=0;i<letters.length();i++)
{
if((letters.charAt(i)>=65&&letters.charAt(i)<=90)||(letters.charAt(i)>=97&&letters.charAt(i)<=122))
result+=letters.charAt(i);
}
System.out.println("result"+result);
You can use Commons-lang.jar to complete this task.The sample code:
word = StringUtils.join(letters);
If you want to write it by yourself.Try below:
public String join(String[] letters){
StringBuffer buffer = new StringBuffer();
for(int idx=0;idx <letters.length;idx++){
buffer.append(letters[idx]);
}
return buffer.toString();
}
public class Main {
public static void main(String[] args) {
String[] letters = new String[3];
letters[0] = "a";
letters[1] = "b";
letters[2] = "c";
StringBuilder word = new StringBuilder();
for (int i = 0; i < letters.length; i++) {
word.append(letters[i]);
}
System.out.println(word);
}
}
I found another way of doing it, How about just this?
System.out.println(Arrays.toString(letters).replaceAll(",|\\s|\\]$|^\\[", ""));
Please note, only use when you don't have space or , in your string
Without going through the char sequence is there any way to reverse String in Java
Try this,
String s = "responses";
StringBuilder builder = new StringBuilder(s);
System.out.println(builder.reverse());
You can use the StringBuilder#reverse() method:
String reverse = new StringBuilder(originalString).reverse().toString();
Use StringBuilder's or StringBuffer's method... reverse()
public class StringReverse
{
public static void main(String[] args)
{
String string=args[0];
String reverse = new StringBuffer(string).reverse().toString();
System.out.println("\nString before reverse: "+string);
System.out.println("String after reverse: "+reverse);
}
}
StringBuffer is thread-safe, where as StringBuilder is Not thread safe..... StringBuilder was introduced from Java 1.5, as to do those operations faster which doesn't have any Concurrency to worry about....
Try reverse() method:
StringBuilder stringName = new StringBuilder();
String reverse = stringName.reverse().toString();
You may use StringBuilder..
String word = "Hello World!";
StringBuilder sb = new StringBuilder(word);
System.out.print(sb.reverse());
If we have to do it:
Without going through the char sequence
One easy way with iteration will be:
public String reverse(String post) {
String backward = "";
for(int i = post.length() - 1; i >= 0; i--) {
backward += post.substring(i, i + 1);
}
return backward;
}
You can use String buffer to reverse a string.
public String reverse(String s) {
return new StringBuffer(s).reverse().toString();
}
one more interesting way to do this is recursion.
public String reverse(String s) {
if (s.length() <= 1) {
return s;
}
return reverse(s.substring(1, s.length())) + s.charAt(0);
}
This is a way to do so using recursion -
public static String reverse(String s1){
int l = s1.length();
if (l>1)
return(s1.substring(l-1) + reverse(s1.substring(0,l-1)));
else
return(s1.substring(0));
}
Using minimal API support. A simple algorithm.
static String reverse(String str) {
char[] buffer = str.toCharArray();
for (int i = 0; i < buffer.length/2; ++i){
char c = buffer[i];
buffer[i] = buffer[buffer.length-1-i];
buffer[buffer.length-1-i] = c;
}
return new String(buffer);
}
Here I have a sample of the same using substring method and o(n) without using any nethods from string . I am aware that using substring will hold complete string memory.
for(int i = 0; i < s.length(); i++) {
s = s.substring(1, s.length() - i) + s.charAt(0) + s.substring(s.length() - i);
System.out.println(s);
}
This might help you!!
public class RevString {
public static void main(String[] args) {
String s="jagan";
String rev="";
for (int i=s.length()-1;i>=0;i--) {
rev=rev+s.charAt(i);
}
System.out.println("Reverse String is: "+rev);
}
}
I have not seen any easy way.
Here is the suitable way to do:
Using the loop:
String d = "abcdefghij";
char b[] = new char[d.length()];// new array;
int j=0; // for the array indexing
for(int i=d.length()-1;i>=0;i--){
b[j] = d.charAt(i); // input the last value of d in first of b i.e. b[0] = d[n-1]
j++;
}
System.out.println("The reverse string is: "+String.valueOf(b));
Output is
The reverse string is: jihgfedcba
The simple logic is:
array[i] = array[n-i];
where i is the Iteration and n is the total length of array
Is there a way to remove integers from TextView in android. For example let's say we have text like this:
123Isuru456Ranasinghe
I want this text to be like this after removing integers
IsuruRanasinghe
How do I achieve this in android?
This will Help you.
public static String removeDigits(String text) {
int length = text.length();
StringBuffer buffer = new StringBuffer(length);
for(int i = 0; i < length; i++) {
char ch = text.charAt(i);
if (!Character.isDigit(ch)) {
buffer.append(ch);
}
}
return buffer.toString();
}
Another Simple Option :
// do it in just one line of code
String num = text.replaceAll(”[\\d]“, “”);
Return your string with Removing Digits.
This is just pure java. Nothing to do with Android.
Here is the code to do what you want.
String str = "123Isuru456Ranasinghe";
String newStr = str.replaceAll("[0-9]", "");
After some tests, it seems that the longest solution is the best in the matter of performance !
public static void main(String[] arg) throws IOException {
// Building a long string...
StringBuilder str = new StringBuilder();
for (int i = 0; i < 1000000; i++)
str.append("123Isuru456Ranasinghe");
removeNum1(str.toString());
removeNum2(str.toString());
}
// With a replaceAll => 1743 ms
private static void removeNum1(String _str) {
long start = System.currentTimeMillis();
String finalString = _str.replaceAll("[0-9]", "");
System.out.println(System.currentTimeMillis() - start);
}
// With StringBuilder and loop => 348 ms
private static void removeNum2(String _str) {
long start = System.currentTimeMillis();
StringBuilder finalString = new StringBuilder();
char currentChar;
for (int i = 0; i < _str.length(); ++i) {
currentChar = _str.charAt(i);
if (Character.isLetter(currentChar)) {
finalString.append(currentChar);
}
}
System.out.println(System.currentTimeMillis() - start);
}
Using a loop is much faster.
But in your case, it is a bit useless :p
Now you have to choose between "slow" and short to write and very fast but a bit more complicated. All depend of what you need.
StringBuilder ans = new StringBuilder();
char currentChar;
for (int i = 0; i < str.length(); ++i) {
currentChar = str.charAt(i);
if (Character.isLetter(currentChar)) {
ans.append(currentChar);
}
}