Replace content of one string with another? - java

How could I replace the letters in a String such as "Hello", with the letters here?
String bubbled = "ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ";
I was initially just doing a replaceAll ("a","ⓐ"), but I feel like there has to be a more efficient way of doing this.

Split bubbled into lowercase and uppercase. Make a new StringBuilder, iterate over each char of source, and if chr >= 'a' && chr <= 'z' append lowercaseBubbled[chr - 'a'], if it's in uppercase range do similar, else just append chr. At the end, use toString on the builder.
Or you could use a slightly less efficient method, replaceChars (since it has to use indexOf) found in Apache Commons. Pro: it's a library, so no extra work for you.

You could use the characters a and ⓐ to determine the offset values for the alphabet. In combination with a StringBuilder it should be rather efficient. Of course you would likely have to be very strict about the input string being only alphabet characters.
This is the code for what I described above:
public class Bubbled {
public static void main(String[] args) {
char bubbledA = 'ⓐ';
int lowerCaseOffset = bubbledA - 'a';
int upperCaseOffset = bubbledA - 'A';
String input = "Hello";
StringBuilder bubbledOutput = new StringBuilder();
for (Character c : input.toCharArray()) {
if (Character.isUpperCase(c)) {
bubbledOutput.append((char)(c + upperCaseOffset));
} else {
bubbledOutput.append((char)(c + lowerCaseOffset));
}
}
System.out.println(bubbledOutput.toString());
}
}
Output
ⓗⓔⓛⓛⓞ

Here is a code snipp that does it. It wont create a zillion String objects. I have only a smaller set of bubble chars just for demo purpose. Please tweak to your liking and no error handling has been done.
public class StackOverFlow {
private static int[] bubbled = {'ⓐ', 'ⓑ', 'ⓒ', 'ⓓ', 'ⓔ'};
private static int [] plain = {'a', 'b', 'c', 'd', 'e'};
private static Map<Integer, Integer> charMap = new HashMap<>();
public static void main(String[] args) {
String test = "adcbbceead";
for(int i=0; i<plain.length; i++) {
charMap.put(plain[i], bubbled[i]);
}
replaceWithBuffer(test);
}
private static void replaceWithBuffer(String test) {
System.out.println("Oginal String = " + test);
StringBuilder sb = new StringBuilder(test);
for(int i =0; i<test.length(); i++) {
int ch = sb.charAt(i);
char buubledChar = (char)charMap.get(ch).intValue();
sb.setCharAt(i, buubledChar);
}
System.out.println("New String = " + sb.toString());
}
}
Output:
Hope this helps :)

Use a for loop:
for (char i='a';i<'z';i++)
str = str.replaceAll(i,bubbled[i-'a']);
for (char i='A';i<'Z';i++)
str = str.replaceAll(i,bubbled[i-'A'+26]);
Of course, this wouldn't be too efficient, since Strings are immutable.

Related

Replace characters within a string using the java replace method

Im a beginner java programmer and I am stuck on a little problem with my university coursework.
Basically I have a string that I want to iterate through and replace all instances of the letter 'a' or 'e' with the letter 'z'. For example, if the original string was "hello alan", the final string should be "hzllo zlzn".
We need to do this using a character array which holds the characters 'a' and 'e' to test against the string.
I've included my code below, we need to use the charAt() method also.
public static void main(String[] args) {
String a = ("what's the craic?");
char letters[] = new char[]{'a', 't'};
System.out.println("Before:" + a);
System.out.println("After: " + removeCharacters(a, letters));
}
public static String removeCharacters(String sentence, char[] letters) {
for (int i = 0; i < sentence.length(); i++) {
for (int j = 0; j < letters.length; j++) {
if (sentence.charAt(i) == letters[j]) {
sentence = sentence.replace(sentence.charAt(i), 'z');
} else {
sentence = "No changes nessesary";
}
}
}
return sentence;
}
Please help me with this problem. Im not sure where I am going wrong! Thanks.
if You are allowed to use replaceAll as well
"hello alan".replaceAll( "[ae]", "z" ); // hzllo zlzn
In difference to replace uses replaceAll a Pattern internally, which is compiled from the first argument [ae] to find the part to substitute with the second argument z. This solution is elegantly short, but slow, because the Pattern has to be compiled each time replaceAll is called.
otherwise use a StringBuilder
char[] letters = new char[] { 'a', 'e' };
StringBuilder buf = new StringBuilder( "hello alan" );
IntStream.range( 0, buf.length() ).forEach( i -> {
for( char c : letters )
if( buf.charAt( i ) == c )
buf.replace( i, i + 1, "z" );
} );
String s = buf.toString(); // hzllo zlzn
In difference to a String the contents of a StringBuilder is mutual (means you can change it). So it only has to be created once and all substitutions can be made in place.
Try this:
public static void main(String[] args) {
String a = "hello alan";
System.out.println("Before:" + a);
System.out.println("After: " + removeCharacters(a));
}
public static String removeCharacters(String sentence) {
if (!sentence.contains("a|e"))
return "No changes necessary";
return sentence.replaceAll("a|e", "z");
}
output 1:
Before:hello alan
After: hzllo zlzn
output 2:
Before:hi world
After: No changes necessary
Since you're forced to use charAt(...), one way would be like this:
public static String removeCharacters(String sentence, char[] letters) {
String output = "";
boolean wasChanged = false;
for (int i = 0; i < sentence.length(); i++) {
char ch = sentence.charAt(i);
for (int j = 0; j < letters.length; j++)
if (ch == letters[j]) {
ch = 'z';
wasChanged = true;
break;
}
output += ch;
}
if (wasChanged)
return output;
else
return "No changes necessary";
}
Since String::replace(char oldChar, char newChar) returns a new string resulting from replacing all occurrences of oldChar in this string with newChar, you do not need nested loops to do it. An efficient way of doing it can be as follows:
public static String removeCharacters(String sentence, char[] letters) {
String copy = sentence;
for (char letter : letters) {
sentence = sentence.replace(letter, 'z');
}
if (sentence.equals(copy)) {
sentence = "No changes nessesary";
}
return sentence;
}
Demo:
public class Main {
public static void main(String[] args) {
// Test
System.out.println(removeCharacters("hello stackoverflow", new char[] { 'a', 'e' }));
System.out.println(removeCharacters("world", new char[] { 'a', 'e' }));
}
public static String removeCharacters(String sentence, char[] letters) {
String copy = sentence;
for (char letter : letters) {
sentence = sentence.replace(letter, 'z');
}
if (sentence.equals(copy)) {
sentence = "No changes nessesary";
}
return sentence;
}
}
Output:
hzllo stzckovzrflow
No changes nessesary

Populating Multidimensional Arrays in Java

So I am trying to populate a 2D array from two strings, as seen below.
However, when I go to compile my code, I get a
"java: incompatible types: char[] cannot be converted to char"
error. What am I doing wrong?
public static void main(String[] args) {
String alphabet = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
String iAlphabet = ("ZYXWVUTSRQPONMLKJIHGFEDCBA");
char alphabetArray [][] = {{alphabet.toCharArray()},{iAlphabet.toCharArray()}};
System.out.print(alphabetArray[4][4]);
}
}
(New to Java, and am just bashing my head against a wall on this one)
I guess you want to be able to translate the character from one string to the other one at the same position:
public static void main(String[] args) {
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String iAlphabet = "ZYXWVUTSRQPONMLKJIHGFEDCBA";
char alphabetArray [][] = {alphabet.toCharArray(),iAlphabet.toCharArray()};
System.out.print("3rd character: " + alphabetArray[0][2] + " -> " + alphabetArray[1][2]);
}
This prints:
3rd character: C -> X
An example of ussage as translate would be:
public static void main(String[] args) {
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String iAlphabet = "ZYXWVUTSRQPONMLKJIHGFEDCBA";
char alphabetArray [][] = {alphabet.toCharArray(),iAlphabet.toCharArray()};
String test = "HELLO WORLD";
StringBuffer translated = new StringBuffer();
for (int i = 0; i < test.length(); i++) {
int index = alphabet.indexOf(test.charAt(i));
if (index > 0) {
translated.append(alphabetArray[1][index]);
} else {
translated.append(test.charAt(i));
}
}
System.out.println("original sentence: " + test);
System.out.println("translated sentence: " + translated.toString());
}
which prints:
original sentence: HELLO WORLD
translated sentence: SVOOL DLIOW
Declare the arrays as shown below. And remember it's not a 26 x 26 array. It is a 2 x 26 array.
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String iAlphabet = "ZYXWVUTSRQPONMLKJIHGFEDCBA";
char alphabetArray [][] = {alphabet.toCharArray(),iAlphabet.toCharArray()};
Print V from the second.
System.out.print(alphabetArray[1][4]);
Print E from the first.
System.out.print(alphabetArray[0][4]);
You are putting an array of char where you need to place the only char. So remove the curly braces and simply put an array of char
Your Code should be like this
public static void main(String[] args) {
String alphabet = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
String iAlphabet = ("ZYXWVUTSRQPONMLKJIHGFEDCBA");
char[] charArray = alphabet.toCharArray();
char[] charArray2 = iAlphabet.toCharArray();
char alphabetArray[][] = { charArray, charArray2 };
System.out.println(alphabetArray[0][23]);
}
you could also take advantage of the fact that the letters 'A'-'Z' are in order
for example: if you want to translate a number to a letter in the alphabet you can just say
char a = 'A';
a+=num;
or if you want it to go backwards
char a = 'Z';
a-=num;
num being the equivelent index you would've given.
this is assuming that you want to make the array read-only of course, and some sort of validation before performing these operations would be recommended. (Verifying the number is positive and less than 26)
if this works in your case, then that's great.
If you want to do a ceaser cipher: IE translate any character by any offset, you can do the following:
private static char offsetChar(char chr, int offset){
chr = Character.toUpperCase(chr);
//value from 0-25 representing letter
int val = chr - 'A';
//make sure that the offset doesn't make it overflow past 26
val = (val + offset) % 26;
// convert back to letter from number 0-25
return (char)('A' + val);
}
also note that this will auto-capitalize the letter, if you don't want that to happen you can test if it is uppercase and return it in the correct state at the end using
Character.isUpperCase and Character.toUpperCase and Character.toLowerCase

How to remove all the characters in char array from a given string recursively without using loops?

I am practicing Java tutorial and I am trying to remove all the characters given in char array from a given string (e.g. array contains 'b', 'm', 'w'. Target string is "big workshop", output: "ig orkshop"). But I cannot use loops and I should do it recursively. I have managed it without recursion but not with recursion.
This is my non-recursive code:
char[] testChars={'E', 'i', 'n'};
String b = new String(testChars);
...
public static String removeChars(String text)
{
return text.replaceAll("[" + b + "]", "");
}
Try this,
public class Example
{
public static void main(String[] agrs) {
String input = "big workshop";
char[] charToRemove = {'b', 'm', 'w'};
String charsToRemove = new String(charToRemove);
StringBuilder sb = new StringBuilder();
Example ex = new Example();
ex.removeChar(input, 0, charsToRemove, sb);
System.out.println(sb);
}
public void removeChar(String input, int index, String charToRemove, StringBuilder target) {
if(input.length() == index) {
return;
}
char c = input.charAt(index);
if(charToRemove.indexOf(c) == -1) {
target.append(c);
}
removeChar(input, index + 1, charToRemove, target);
}
}
Try:
public static String removeChars(String text, char[] chars) {
return removeChars(text, chars, 0);
}
private static String removeChars(String text, char[] chars, int currentIndex) {
if(currentIndex == chars.length) {
return text;
}
char currentChar = chars[currentIndex];
String removed = text.replace(currentChar.toString(), "");
return removeChars(removed, chars, currentIndex + 1);
}
When trying to use recursion, you have two remember that you are either at a base case or taking a step toward it.
For example: your base case could be the end of the string. You have two possibilities at each recursive level.
1) you are at the end of the string: return an empty string to use as a building base.
2) you are not at the end of the string: you can check the first character and pass the rest of the string to a recursive call.
See the example below. This is not tested code but should point you in the right direction.
public String recursiveRemove (String[] arr, String str){
// first check if at the base case
if (str.length() == 0) {
return "";
}
// else handle character, and reduce to approach base case
String character = str.substring(0,1);
// contains is not a method but just to show the logic being used here
if (arr.contains(character)){
//replace character with empty sting to remove it from the result
character = "";
}
// return the character (or empty string) with the result of the
// recursive call appended onto the end
return character + recursiveRemove(arr, str.substring(1));
}
You can replace for-loops this way:
public void replaceFor(int i , Predicate<Integer> p , Consumer<Integer> c , Function<Integer , Integer> f)
{
//check whether the termination-condition is true
if(!p.test(i))
return;
//this consumer does what would be in the for-loop
c.accept(i);
//continue with the next value for i
replaceFor(f.apply(i) , p , c , f);
}
A basic for-loop replacement that prints all numbers from 0 to 10 would look like this:
replaceFor(0 , i -> i <= 10 , i -> System.out.println(i) , i -> ++i);
Here is a solution that
Maintains your method signature
Does not mask iteration with recursion
Teaches you divide and conquer
Note, I'm not thrilled about the testChars field, but it looks like you already had that in your iterative version.
private final static char[] testChars = {'b', 'm', 'w'};
public static String removeChars(String text) {
switch (text.length()) {
case 0:
return "";
case 1:
char asChar = text.charAt(0);
for (char testChar : testChars) {
if (asChar == testChar) {
return "";
}
}
return text;
default:
int middle = text.length() / 2;
String firstHalf = text.substring(0, middle);
String lastHalf = text.substring(middle);
return removeChars(firstHalf) + removeChars(lastHalf);
}
}
public static void main(String... args) {
System.out.println(removeChars("big workshop"));
}

Alternating string of characters and digits

I was given this problem to solve. I have only the slightest idea on how it should be implemented, and I'm all too new with programming and stuffs, and would love to hear your comments on this.
Say given a string in the form "abc1234defgh567jk89", and I must create a new string "a1b2c3d5e6f7j8k9".
Note that there are corresponding [digits] & [characters] group and since there may be more of one type over the other, the output has only matching sequence and ignore extra digits or characters in this case '4' & 'g' & 'h'.
I know I will have to use 2 sets of queues to store both types of elements, but I do not know how else to proceed from here.
Would appreciate if you could share a pseudocode or a Java(prefably) version, since I am learning thru this language now.
Thank you.
Pseudocode:
Queue letterQueue;
Queue numberQueue;
for (every character in the string) {
if (it's a letter) {
if (numberQueue is not empty) {
add the letters alternating into the buffer (stringbuilder), and purge buffers
}
add newest letter to letterqueue
}
if (it's a number) {
add newest letter to numberqueue
}
}
add any remaining unprocessed letters to the queue (this will happen most of the time)
return contents of string buffer
You will need:
Queue, probably a LinkedList
StringBuilder
String.toCharArray
Character
Code:
import java.util.LinkedList;
import java.util.Queue;
public class StringTest {
private static String str ="abc1234defgh567jk89";
private static String reorganize(String str) {
Queue<Character> letterQueue = new LinkedList<>();
Queue<Character> numberQueue = new LinkedList<>();
StringBuilder s = new StringBuilder();
for (char c : str.toCharArray()) {
if(Character.isLetter(c)) {
if (!numberQueue.isEmpty()) processQueues(letterQueue, numberQueue, s);
letterQueue.offer(c);
} else if(Character.isDigit(c)) {
numberQueue.offer(c);
}
}
processQueues(letterQueue, numberQueue, s);
return s.toString();
}
private static void processQueues(Queue<Character> letterQueue, Queue<Character> numberQueue, StringBuilder s) {
while(!letterQueue.isEmpty() && !numberQueue.isEmpty()) {
s.append(letterQueue.poll());
s.append(numberQueue.poll());
}
letterQueue.clear();
numberQueue.clear();
}
public static void main(String... args) {
System.out.println(reorganize(str));
}
}
See this hint:
String str = "abc1234defgh567jk89";
String c = str.replaceAll("\\d", ""); // to store characters
String d = str.replaceAll("\\D", ""); // to store digits
Try this:
public static void main(String[] args) {
String str = "abc1234defgh567jk89";
String c = str.replaceAll("\\d", "");
String d = str.replaceAll("\\D", "");
String result = "";
int j = 0, k = 0;
int max = Math.max(c.length(), d.length());
for (int i = 0; i < max; i++) {
if (j++ < c.length())
result = result + c.charAt(i);
if (k++ < d.length())
result = result + d.charAt(i);
}
System.out.println(result);
}
Output:
a1b2c3d4e5f6g7h8j9k

how to delete a particular character at particular position from a character array ?

I need to delete a character from a character array and re-size the array. Until now, I have worked on replacing a particular character with a special character.
In this code I am searching for any matches that are found i.e , if any characters are matching in the male and female character array and if found I am replacing it with "*". Instead of that I have to delete that character and resize the array.
private static void Compare(String Male,String Female) {
char[] male;
char[] female;
// converting a string into charecter array
male=Male.toCharArray();
female=Female.toCharArray();
//finding any matches i.e, any charecter is matching or not
for(int i=0;i<male.length;i++){
for(int j=0;j<female.length;j++)
{
String m = Character.toString(male[i]);
String fm = Character.toString(female[j]);
if(m.equals(fm)){
//if the charecters are equal then replacing them with "*"
male[i]='*';
female[j]='*';
}
}
}
Try this:
String male = "maleg*$m-z";
String female= "femal^\\$e-is";
String deletedMale = male.replaceAll("["+Pattern.quote(female)+"]", "");
String deletedFemale = female.replaceAll("["+Pattern.quote(male)+"]", "");
System.out.println(deletedMale);
System.out.println(deletedFemale);
You could use the ArrayUtils class within the org.apache.commons.lang
library to make this a little easier:
Array Utils Link
public static void main(String[] args) {
String Male = "male";
String Female = "female";
char[] male;
char[] female;
// converting a string into charecter array
male=Male.toCharArray();
female=Female.toCharArray();
//finding any matches i.e, any charecter is matching or not
for(int i=0;i<male.length;){
boolean remove = false;
for(int j=0;j<female.length;)
{
String m = Character.toString(male[i]);
String fm = Character.toString(female[j]);
if(m.equals(fm)){
//if the charecters are equal then replacing them with "*"
female = ArrayUtils.remove(female, j);
remove = true;
}else{
j++;
}
}
if(remove)
{
male = ArrayUtils.remove(male, i);
}else{
i++;
}
}
System.out.println(male);
System.out.println(female);
}
Well, there are quite a few concerns with your code. Namely, the lack of conventions, no return value, and little to no clarity on what the problem actually is.
Anyway, this will remove duplicates only if the character appears in both strings.
private static void compare(String male, String female) {
List<Character> male1 = addAll(male.toCharArray());
List<Character> female1 = addAll(female.toCharArray());
for (int i = 0; i < male1.size(); i++) {
Character c = male1.get(i);
if (female1.contains(c)) {
while (male1.remove(c)) {
i--;
}
while (female1.remove(c));
}
}
// Do whatever else here, unless you need a char array, then convert it
// if you need to.
char[] maleA = toArray(male1);
char[] femaleA = toArray(female1);
System.out.println(new String(maleA));
System.out.println(new String(femaleA));
}
Here are the methods referenced in the above code.
private static char[] toArray(List<Character> list) {
char[] array = new char[list.size()];
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}
return array;
}
private static List<Character> addAll(char[] array) {
List<Character> list = new ArrayList<Character>();
for (char c : array) {
list.add(c);
}
return list;
}
If you need to use other data types, just make a generic version, or change it.
You can achieve this easily using the following function:
String original_str="HOLLOW POOL";
String newone=original_str.replace("O", "*"); //Replaces the char "O" with "*"
System.out.print(newone);
The result will be H*LL*W P**L
That's it!!

Categories

Resources