Replace vowel with next does not work - java

I have a string input and want to replace every vowel in that string with its next vowel.
However, it does not seem to work correct. I have tried various input like:
venky -> vinky // Correct
ui -> uo // Incorrect, expected ao
ai -> ao // Incorrect, expected eo
The vowel order is
char[] vowels = { 'a', 'e', 'i', 'o', 'u' };
My code is:
package test;
import java.util.Scanner;
public class Problem1 {
public static void main(String args[]) {
Scanner r = new Scanner(System.in);
String str, res;
char ch;
int i, j;
char[] vowels = { 'a', 'e', 'i', 'o', 'u' };
System.out.println("Enter a string");
str = r.nextLine();
res = str;
for (i = 0; i < str.length(); i++) {
ch = str.charAt(i);
for (j = 0; j < 4; j++) {
if (ch == 'u') {
res = str.replace(ch, 'a');
break;
} else if (ch == vowels[j]) {
res = str.replace(ch, vowels[j+1]);
break;
}
}
}
System.out.println("String after replacing the vowels with next vowel : "
+ res);
}
}

Your problem is here:
res = str.replace(ch, vowels[j+1]);
Consider the input ai. The 1st time you pass here you change the value of res to ei, the second time you replace the i in the initial string ai, not in the modified one. So res gets the new value ao.
Anyway, even if you fix this particular case you may hit some other issue with longs words containing many wovels as you replace the first occurence (imagine the case of ae you would get ie). You should build the result one char at a time, with either the unmodified letter or the next wovel.

You are replacing the vowel in your str variable and saving it to res then you break and continue on your str which has the previous vowel not replaced.
You would need put your response together char by char

Your problem is String.replace will replace all occurrence of a char in your String.
Since you traverse over your String, one original character might be replaced multiple times, for example:
acac -> ecec -> ecic
You will receive ecic instead of ecec.
So I think you can create another String based on the current Strin to avoid the sideeffect of String.replace:
char[] output = new char[str.length()];
for(i = 0; i < str.length(); i++) {
ch = str.charAt(i);
for (j = 0; j < 4; j++) {
if (ch == 'u') {
output[i] = 'a';
} else if(ch == vowels[j]) {
output[i] = vowels[j+1];
} else {
output[i] = ch;
}
}
}
String res = new String(output);

res = str.replace(ch, vowels[j+1]);
will replace the string value and put in res variable but on the next time it will not use the old res variable for further modification thats why it is giving wrong answer try changing.
str = str.replace(ch, 'a');
str = str.replace(ch, vowels[j+1]);
and print str instead of len

Related

How do I replace one character occurrence in a string?

How would I replace a string like "Hello" with "Helko", only replacing the second L but not the first?
Use replaceAll with regular expression:
System.out.println("Hello".replaceAll("((?!^).*?|[^l]*l.*?)l","$1k"));
Simple Approach (based on excluding the second l):
Search for first index of l using indexOf and do another search for l but this time start searching from firstL + 1 which will lead to the second index l if exist!
Do a test if there is second l, If So Exclude the second l by using substring which take only the first part (start from zero till secondL) and second part (start from secondL+1 till the end), Concatenate them with k.
public static String removeSecondL(String str) {
int firstL = str.indexOf('l');
int secondL = str.indexOf('l', firstL+1);
if(secondL != -1) {
String firstPart = str.substring(0, secondL);
String secondPart = str.substring(secondL + 1);
return firstPart + 'k' + secondPart;
}
return str;
}
Tests:
public static void main(String[] args) {
System.out.println(removeSecondL("Hello")); // Helko
System.out.println(removeSecondL("lololo")); // lokolo
System.out.println(removeSecondL("no l")); // no l
}
Another Approach: Convert the String into a char array, and declare a variable lFound gonna look for the first occurrence of letter l, if it found next l will be converted to k and exit the loop by break.
String str = "Hello";
char[] chars = str.toCharArray();
boolean lFound = false;
for (int i = 0; i < chars.length; i++) {
if(lFound) {
if(chars[i] == 'l')
{
chars[i] = 'K';
break;
}
}else {
lFound = chars[i] == 'l'; //if(chars[i] == 'l') lFound = true;
}
}
System.out.println(chars); //HelKo
Lately, I turned to the conversation and I saw you writing:
I wanted to replace one instance of a character with another, like "aaaaa" with "aabaa", where only the third 'a' is replaced with 'b', but not the others.
Just follow second approach I posted with additional tests.
public static char[] removeSpecificChar(String str, char a, char b, int position) {
char[] chars = str.toCharArray();
int pos = 1;
for (int i = 0; i < chars.length; i++) {
if(pos == position) {
if(chars[i] == a)
{
chars[i] = b;
break;
}
}else {
pos += (chars[i] == a) ? 1 : 0;
}
}
return chars;
}
Test:
String str = "aaaaa";
System.out.println(removeSpecificChar(str, 'a', 'b', 3));
Print:
aabaa

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

Incorrect output in small program. Why is this String variable not doing what I want it to?

This program should take a String, check if each letter is a vowel and change the vowels into underscores. For example, if I enter some it should output s_m_. This is a simple programming exercise that I feel like I should be able to do. However I am genuinely stumped and can't tell what I'm doing wrong.
I have declared an array to keep the vowels, a newStr variable which will contain the updated string ,and I'm looping through the string, comparing each letter using charAt() to check if it's in the vowels array. If it is, I add _ to the updated String, and I keep the original letter if it's not. The final output is wrong, what am I doing wrong?
char[] vowels = { 'a', 'e', 'i', 'o', 'u' };
String newStr = "";
for (int x = 0; x < str.length(); x++) {
char letter = str.charAt(x);
for (int j = 0; j < vowels.length; j++) {
if (letter == vowels[j]) {
newStr = newStr + '_';
break;
} else {
newStr = newStr + letter;
break;
}
}
}
out.println(newStr);
In your code the issue is within your nested "for-loop". I say this in quotes because it never actually loops. The first iteration j=0 immediately breaks the loop since either your letter is equal to a with (letter == vowels[0]) or not. In either case you do a break; and append the character. This means your loop can be reduced to a simple if-else that checks if the letter is an a and replaces it with _ or keeps it.
To fix this issue you need to use a different approach. You can create a String of vowels such as "aeiouAEIOU" and use indexOf to test whether the selected character is a vowel.
public static String omitVowels(String input) {
StringBuilder out = new StringBuilder(input.length());
String vowels = "aeiouAEIOU";
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (vowels.indexOf(c) >= 0) // is vowel if index not negative
out.append('_');
else
out.append(c);
}
return out.toString();
}
indexOf(char) will return -1 if the provided character is not part of the string, else it will return the specific index. We can use this property to test whether the character is a vowel or not.
Examples
omitVowels("hello world") -> "h_ll_ w_rld"
omitVowels("aeiou") -> "_____"
omitVowels("TESTing") -> "T_ST_ng"
This is pretty simple. Just iterate over each character of the given string and replace with _ in case of it is vowel.
Use StringBuilder
Be ware of using String. This is immutable in java, therefore to build final string, you should use StringBuilder.
public static String replaceVowel(String str) {
final IntPredicate isVowel = ch -> ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u';
StringBuilder buf = new StringBuilder(str.length());
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
boolean vowel = isVowel.test(Character.toLowerCase(ch));
buf.append(vowel ? '_' : ch);
}
return buf.toString();
}
Use RegularExpression
As alternative, you can use Regular Expression with replaceAll() method of the String class.
private static final Pattern VOWEL = Pattern.compile("[aeiou]");
public static String replaceVowel(String str) {
return VOWEL.matcher(str).replaceAll("_");
}
This is also correct, because in the background, replaceAll() uses StringBUilder.
for (int x = 0; x < str.length(); x++) {
char letter = str.charAt(x);
boolean toReplace = false;
for (int j = 0; j < vowels.length; j++) {
if (letter == vowels[j]) {
toReplace = true;
break;
}
}
if (toReplace) {
newStr = newStr + "_";
} else {
newStr = newStr + letter;
}
}

Java Letter changes arraylist to string without commas but including white spaces

Trying to complete this challenge from coderbyte: "Using the Java language, have the function LetterChanges(str) take the str parameter being passed and modify it using the following algorithm. Replace every letter in the string with the letter following it in the alphabet (ie. c becomes d, z becomes a). Then capitalize every vowel in this new string (a, e, i, o, u) and finally return this modified string."
The problem that i am having is the replace is pulling on the white spaces between characters, but I need it to preserve white spaces between words. Is there a better solution to this?
import java.util.Arrays;
import java.util.Scanner;
public class nextLetter {
public static String LetterChanges(String str) {
String[] inputString = str.replaceAll("[^a-zA-Z ]", "").split("");
String[] alph= "abcdefghijklmnopqrstuvwxyz".split("");
String[] vowel ="aeiouy".split("");
for(int i=0; i<inputString.length; i++){
int index= Arrays.asList(alph).indexOf(inputString[i])+1;
inputString[i]= alph[index];
if(Arrays.asList(vowel).indexOf(inputString[i])>0){
inputString[i]= inputString[i].toUpperCase();
}
}
//System.out.println(Arrays.toString(inputString));
return Arrays.toString(inputString)
.replace(" ","")
.replace(",", "") //remove the commas
.replace("[", "") //remove the right bracket
.replace("]", "")//remove the left bracket
.replace(" ","")
.trim();
}
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("enter a sentence");
System.out.print(LetterChanges(s.nextLine()));
}
}
Also I would not mind any pointers on how to improve this!
Note: I've changed the method name to something a bit more descriptive. The method assumes that you're only working with lowercase letters.
public static void main(String[] args){
System.out.println(shiftLetters("abcdz")); //bcdea
}
public static String shiftLetters(String str){
StringBuilder shiftedWord = new StringBuilder();
for (int i = 0; i < str.length(); i++){
char currentChar = str.charAt(i);
if (currentChar != ' '){
currentChar += 1;
if (currentChar > 'z'){
currentChar = 'a';
}
}
shiftedWord.append(currentChar);
}
return shiftedWord.toString();
}
This is the general logic flow of this program: create a cumulative StringBuilder object that will eventually be the return value of the method. Loop through all characters in the string; if the character is a whitespace character, then simply don't bother with it and add it onto the StringBuilder as is. Else, add one to the current character. Note that chars are an integral(4.2.1) primitive type, so you may add ints to a char as such. If it's the special case that the new char is out of the normal a-z range, set it back to a.
Taking Use of Java 8's API
public static String functionalShiftLetters(String str){
return str
.chars()
.map(c -> c != ' ' ? c + 1 : c)
.map(c -> c > 'z'? 'a' : c)
.collect(StringBuilder::new,
StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
}
This preserves all other characters and handles the vowels.
public static String LetterChanges(String str)
{
str = str.toLowerCase();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++)
{
char c = str.charAt(i);
if ('a' <= c && c <= 'z')
{
c = (c == 'z') ? 'a' : (char) (c + 1);
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')
{
c = Character.toUpperCase(c);
}
}
sb.append(c);
}
return sb.toString();
}
Input: abcdefghijklmnopqrstuvwxyz 1234567890
Output: bcdEfghIjklmnOpqrstUvwxyzA 1234567890
If have fixed alphabeth and swapping algorithm you can use a static dictionary.
public static HashMap<String,String> dictionary = new HashMap<>();
static{
dictionary.put(" ", " ");
dictionary.put("a", "b");
dictionary.put("b", "c");
dictionary.put("c", "d");
dictionary.put("d", "E");
.
.
dictionary.put("z", "A");
}
public static String shiftLetters(String str){
StringBuffer response = new StringBuffer();
for (int i = 0; i < str.length(); i++){
response.append(dictionary.get(String.valueOf(str.charAt(i))));
}
return response.toString();
}

Compare a char to an array of chars?

package loopPractice;
import java.util.Scanner;
public class replaceVowels {
static Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
System.out.print("Enter a string: ");
String s = sc.nextLine();
String originalString = s;
char[] vowels = {'a', 'e', 'i', 'o', 'u'};
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c.equals(vowels[i])){
String front = s.substring(0, i);
String back = s.substring(i + 1);
s = front + "" + back;
}
}
System.out.println(originalString);
System.out.println(s);
}
}
The job is to replace all vowels in a word, How can i replace every vowel using an array of vowels?
The question is: Write a method that returns a String that is a copy of a String parameter, but without any vowels
Well, in the spirit of your question, you could write a new function that checks if an array contains a character:
public static void main(String[] args) {
System.out.print("Enter a string: ");
String s = sc.nextLine();
String originalString = s;
char[] vowels = {'a', 'e', 'i', 'o', 'u'};
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (contains(c, vowels)) {
String front = s.substring(0, i);
String back = s.substring(i + 1);
s = front + "" + back;
}
}
System.out.println(originalString);
System.out.println(s);
}
private static boolean contains(char c, char[] arr) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == c) {
return true;
}
}
return false;
}
There are three big problems with this code.
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c.equals(vowels[i])){
String front = s.substring(0, i);
String back = s.substring(i + 1);
s = front + "" + back;
}
}
First, you can't use equals on a char, since char is a primitive type. Use ==.
Second, you're not checking for vowels properly. The above code compares the 0'th character of 's' to the 0'th character in the vowels array; that is, it compares it to 'a' but not to any other vowel. Similarly, it compares the character at index 1 to 'e', but not any other vowel, the character as 2 to 'i', etc.; when you get up to index 5, the program will throw an exception because vowels isn't that big.
The solution is that you need a double loop (or nested loop). For each character in s, you will need to check it against every character in the vowels array (or at least until you hit a match). So you'll need something like
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
boolean isAVowel = false;
for (int j = 0; j < vowels.length; j++) {
if (c == vowels[j]) {
isAVowel = true;
break; // will leave the inner loop but not the outer loop
}
// I'll let you finish the rest
As #cptcactus demonstrated in his answer, moving the inner loop to a new method is a good way to implement this kind of solution.
The third problem is more subtle. When you're looping through indexes in an array or string, and the loop removes elements from the array or string, you have to be very careful because the indexes will shift. Suppose your code did approximately this:
for (int i = 0; i < s.length(); i++) {
if [[[ s.charAt(i) is a vowel ]]] {
[[[ remove the i'th character from s; ]]]
}
}
Say s is "air". First i is set to 0, and s.charAt(i) is 'a'. This is a vowel, so we remove it. This means s is now "ir". Then we loop back and set i to 1. Now s.charAt(i) is 'r' since it uses the new value of s, and it never looks at the vowel 'i'.
A couple ways to work around that problem are:
make sure i is not incremented if you remove a character from it (you could use i-- which will cancel out the i++);
go backwards through the indexes (i.e. start with s.length()-1 and decrement) instead of forwards.
(There are other ways to solve this, by using the replaceAll method or a Set<Character>, but I'm assuming that this is a class and your purpose is to learn the basics of loops and such.)
String.replaceAll("[aeiou](?!\\b)", "");
Reads: Match all vowels ([aeiou]) that are not followed ((?!...)) by an "end of word" (\b). For more information read the Javadoc on java.util.regex.Pattern;
even simpler would be this (equivalent but simpler) regex:
String.replaceAll("[aeiou]\\B", "");

Categories

Resources