removing vowels from array - java

The instructions >>
Implement the method named removeVowels which processes the array of strings named words by printing each string from words with only non-vowels on its own line.
For example, if words contains:
{"every", "nearing", "checking", "food", "stand", "value"}
The method should output:
vry
nrng
chckng
fd
stnd
vl
So far, I have:
public class U6_L3_Activity_Two {
public static void removeVowels(String[] hit_str) {
char vowels = {
'a',
'e',
'i',
'o',
'u',
'A',
'E',
'I',
'O',
'U'
};
for (int i = 0; i < hit_str.length; i++) {
if (find(vowels.begin(), vowels.end(),
hit_str[i]) != vowels.end()) {
hit_str = hit_str.replace(i, 1, "");
i -= 1;
}
}
return hit_str;
}
}
Runner:
import java.util.Scanner;
public class runner_U6_L3_Activity_Two
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("Enter array length:");
int len = scan.nextInt();
scan.nextLine();
String[] wordList = new String[len];
System.out.println("Enter values:");
for(int i = 0; i < len; i++)
{
wordList[i] = scan.nextLine();
}
U6_L3_Activity_Two.removeVowels(wordList);
}
}
The error message i'm getting says:
U6_L3_Activity_Two.java:3: error: illegal initializer for char
char vowels = {
^
I've tried a bunch of different ways to make a list of vowels but none of them seem to work.

Try replacing vowels with this built-in method:
String[] hit_str = { "every", "nearing", "checking", "food", "stand", "value" };
for (String str : hit_str) {
System.out.println(str.replaceAll("[AaEeIiOoUu]", ""));
}
Here, the for loop iterates over your input string/s and uses Regex to check if char(s) is/are found from the provided Regex. [AaEeIiOoUu] tries to match all chars of Regex individually in the string chars. Using Regex is better than declaring a char[] as it improves code readability and saves us from writing complex logics.

There're many way to do this. I reccomen to split 2 tasks: remove vowels and print the results.
private static final Pattern VOWELS = Pattern.compile("(?i)[aeiou]");
public static String[] removeVowels(String[] words) {
return Arrays.stream(words)
.map(word -> VOWELS.matcher(word).replaceAll(""))
.toArray(String[]::new);
In case you are able to modife the original array, you can avoid creation of the new one.
public static String[] removeVowels(String[] words) {
for (int i = 0; i < words.length; i++)
words[i] = VOWELS.matcher(words[i]).replaceAll("");
return words;
}

Assumptions
This looks like a college class task. So, I'm going to answer assuming that you can't use more advanced data structures such as List, Set, etc. I'm also going to assume that you can't box and unbox your primitives (i.e. change int to Integer). If I recall from my college courses, the main point of these tasks is to learn to implement basic logic and loops. This means you don't need to use advanced Java features such as Pattern and Stream.
This means that we need to stick with primitives, basic arrays, basic loops, and basic java functionality. This also means that the code likely isn't going to be efficient, but it will meet the requirements of your course.
Error Message
Your Error message says
"illegal initializer for char"
You are trying to shove an array into a single character. You can't do that. Put some brackets after char, and your error message should go away.
char[] vowels = {
'a',
'e',
'i',
'o',
'u',
'A',
'E',
'I',
'O',
'U'
};
That being said, don't use this. It's clunky and error prone. There are better ways.
Remove Vowels Method
That's not the only problem with your code though. Your void method removeVowels has a return value. void methods don't return anything.
Working through the task
Since the instructions say you have to receive an array of Strings, we know that your method, at a minimum, should look something like
void removeVowels(String[] hit_str);
or
String[] removeVowels(String[] hit_str);
Since you can modify the String array without having to pass it around, the void method should work fine. So, now we can look at what the method should do. Here's some pseudo code:
void removeVowels(String[] hit_str){
for (int i = 0; i < hit_str.length; i++) {
// if hit_str[i] contains a vowel, then remove it <-- Pseudo Code
}
}
Fleshing out the Pseudo Code
At the point we hit the pseudo code, we know that hit_str[i] is a value within the array, and we know that it is a String. Since String extends Java's Object, we know that it can be null. We also know that "" is a valid empty String. We also know that "cdf" is also a valid String which doesn't contain any vowels.
So, we know that we should account for a null value in the array, as well as a value that has a length of 0, and a value that already matches our required criteria of no vowels.
So, our pseudo code now looks something like this
// this could also be if (hit_str[i] != null ...
if (Objects.nonNull(hit_str[i]) && !hit_str[i].isEmpty()) {
// remove vowels if they exist
}
Getting to work
Now that we finally have a String to work with, how do we remove the vowels from it. Since our object is a String, java has a lot of methods to help us. The best method would be replaceAll.
replaceAll uses a regex pattern to find any elements in the String that match the pattern, and replaces them with your designated replacement. Our Regex would look like this "(?i)[aeiou]". It can be a bit confusing at first, but the elements in parentheses are the modifiers. The ? says match everything after, and the i means case insensitive. The elements in the brackets are the elements to match. So, this regex says to match everything in the string, case insensitive, against the letters in the brackets.
Example:
String myString = "Look at all the vowels aeiou and AEIOU both upper and lower case";
System.out.println(myString.replaceAll("(?i)[aeiou]", ""));
This code produces Lk t ll th vwls nd bth ppr nd lwr cs.
Putting it together
So, our final code would look something like this.
void removeVowels(String[] hit_str){
for (int i = 0; i < hit_str.length; i++) {
if (Objects.nonNull(hit_str[i]) && !hit_str[i].isEmpty()) {
hit_str[i] = hit_str[i].replaceAll("(?i)[aeiou]", ""));
}
}
}
Using the method
Your main method should now look like this after the String[] array has been created.
removeVowels(wordList);
for (int i = 0; i < wordList.length; i++) {
System.out.println(wordList[i]);
}

Related

Java method not doing what expected. Trying to understand why

Trying to write a java method that will take a string, loop through it and where it finds a vowel (A,E,I,O,U,Y) replace it with the vowel plus "OB".
I've written the below but it isn't working as I'd expect and doesn't seem to be matching the current character in my string with the vowels from my list. (The program compiles and runs so it isn't an issue with not importing necessary bits at the beginning. The input string will always be uppercase and only contain alphas.) I'm struggling to figure out where I'm going wrong.
Can anyone help?
public static String obifyText(String text) {
String[] myList = new String[] {"A","E","I","O","U","Y"};
StringBuilder tempText = new StringBuilder(text);
String obify = "OB";
for (int i = 0; i < text.length() -1 ; i ++ ) {
if ( Arrays.asList(myList).contains(tempText.charAt(i)) ) {
System.out.println(tempText.charAt(i)+" found.");
tempText = tempText.insert((i+1),obify);
}
}
text = tempText.toString();
return text;
}
Don't play with indexes.
Managing with indexes could be difficult when you are dealing with changing the string.
Loop on the chars itself as follows:
public static void main(String[] args){
String[] myList = new String[] {"A","E","I","O","U","Y"};
String text = "AEE";
StringBuilder tempText = new StringBuilder("");
String obify = "OB";
for (char c : text.toCharArray()){
tempText = tempText.append(c);
if ( Arrays.asList(myList).contains(c+"") ) {
System.out.println(c+" found.");
tempText = tempText.append(obify);
}
}
text = tempText.toString();
System.out.println(text);
}
OUTPUT:
A found.
E found.
E found.
AOBEOBEOB
charAt returns a char, but myList stores String elements. An array of Strings can never contain values of char. Your if statement never runs.
You can convert the char value to a string:
Arrays.asList(myList).contains(Character.toString(tempText.charAt(i)))
There's just one more problem with your code.
When the code inserts OB after a vowel, there is a side effect: a new vowel O is created. Your code then tries to insert OB after the new O. This is undesired, right?
To make it not do this, you can loop from the end of the string to the start:
for (int i = text.length() - 1; i >= 0 ; i--) {
If this is not a homework question to practice using StringBuilder or for loops, here's a one liner solution using regex:
return text.replaceAll("([AEIOUY])", "$1OB");
You compare two different types in Arrays.asList(myList).contains(tempText.charAt(i)), Arrays.asList(myList) is a List<String> and tempText.charAt is a char. So the contains check will never result in true.
One possible fix, change myList to Character[]
Character[] myList = new Character[] {'A','E','I','O','U','Y'};
There is another problem with the actual insertion, see Pankaj Singhal answer for a solution to that.

How can I put multiple parts of a string into a list?

So the goal is to look for patterns like "zip" and "zap" in the string, starting with 'z' and ending with 'p'. Then, for all such strings, delete the middle letter.
What I had in mind was that I use a for loop to check each letter of the string and once it reaches a 'z', it gets the indexOf('p') and puts that and everything in the middle into an ArrayList, while deleting itself from the original string so that indexOf('p') can be found.
How can I do that?
This is my code so far:
package Homework;
import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;
public class ZipZap {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
List < String > list = new ArrayList < String > ();
System.out.print("Write a sentence with no spaces:");
String sen = in .next();
int len = sen.length();
int p1 = sen.indexOf('p');
String word = null;
String idk = null;
for (int i = 0; i < len; i++) {
if (sen.charAt(i) == 'z') {
word = sen.substring(i, p1 + 1);
list.add(word);
idk = sen.replace(word, "");
i = 0;
}
}
}
}
use this , here i am using "\bz.p\b" pattern for finding any word that contains starting char with z and end with p anything can be in between
String s ="Write a sentence with no zip and zap spaces:";
s=s.replaceAll("\\bz.p\\b", "zp");
System.out.println(s);
output:
Write a sentence with no zp and zp spaces:
or it can be
s.replaceAll("z\\w+p", "zp");
here you can check you string
https://regex101.com/r/aKaNTJ/2
I think you’re saying that input zipzapityzoop, for example, should be changed to zpzpityzp with i, a and oo going into list. Please correct me if I misunderstood your intention.
You are on the way and seem to understand the basics. The issues I see are minor, but of course you want to fix them:
As #RicharsSchwartz mentions, to find all strings like zip, zap and zoop, you need to find p after every z you find. When you have found z at index i, you may use sen.indexOf('p', i + 1) to find a p after the z (the second argument causes the search to begin at that index).
Every time you have found a z, you are setting i back to 0, this starting over from the beginning of the string. No need to do that, and this way your program will never stop.
sen.substring(i, p1+1) takes out all of zip when I understood you only wanted i. You need to adjust the arguments to substring().
Your use of sen.replace(word, "") will replace all occurences of word. So once you fix your program to take out a from zap, zappa will become zpp (not zppa), and azap will be zp. There is no easy way to remove just one specific occurrence of a substring from a String. I think the solution is to use the StringBuilder class. It has a delete method that will remove the part between two specified indices, which is what you need.
Finally you are assigning the changed string to a different variable idk, but then you continue to search sen. This is like assigning zpzapityzoop, zipzpityzoop and zipzapityzp to idk in turn, but never zpzpityzp. However, if you use a StringBuilder as I just suggested, just use the same StringBuilder all the way through and you will be fine.

Removing special character without using Java Matcher and Pattern API

I am trying to write one java program. This program take a string from the user as an input and display the output by removing the special characters in it. And display the each strings in new line
Let's say I have this string Abc#xyz,2016!horrible_just?kidding after reading this string my program should display the output by removing the special characters like
Abc
xyz
2016
horrible
just
kidding
Now I know there are already API available like Matcher and Patterns API in java to do this. But I don't want to use the API since I am a beginner to java so I am just trying to crack the code bit by bit.
This is what I have tried so far. What I have done here is I am taking the string from the user and stored the special characters in an array and doing the comparison till it get the special character. And also storing the new character in StringBuilder class.
Here is my code
import java.util.*;
class StringTokens{
public void display(String string){
StringBuilder stringToken = new StringBuilder();
stringToken.setLength(0);
char[] str = {' ','!',',','?','.','_','#'};
for(int i=0;i<string.length();i++){
for(int j =0;j<str.length;j++){
if((int)string.charAt(i)!=(int)str[j]){
stringToken.append(str[j]);
}
else {
System.out.println(stringToken.toString());
stringToken.setLength(0);
}
}
}
}
public static void main(String[] args){
if(args.length!=1)
System.out.println("Enter only one line string");
else{
StringTokens st = new StringTokens();
st.display(args[0]);
}
}
}
When I run this code I am only getting the special characters, I am not getting the each strings in new line.
One easy way - use a set to hold all invalid characters:
Set<Character> invalidChars = new HashSet<>(Arrays.asList('$', ...));
Then your check boils down to:
if(invaidChars.contains(string.charAt(i)) {
... invalid char
} else {
valid char
}
But of course, that still means: you are re-inventing the wheel. And one does only re-invent the wheel, if one has very good reasons to. One valid reason would be: your assignment is to implement your own solution.
But otherwise: just read about replaceAll. That method does exactly what your current code; and my solution would be doing. But in a straight forward way; that every good java programmer will be able to understand!
So, to match your question: yes, you can implement this yourself. But the next step is to figure the "canonical" solution to the problem. When you learn Java, then you also have to focus on learning how to do things "like everybody else", with least amount of code to solve the problem. That is one of the core beauties of Java: for 99% of all problems, there is already a straight-forward, high-performance, everybody-will-understand solution out there; most often directly in the Java standard libraries themselves! And knowing Java means to know and understand those solutions.
Every C coder can put down 150 lines of low-level array iterating code in Java, too. The true virtue is to know the ways of doing the same thing with 5 or 10 lines!
I can't comment because I don't have the reputation required. Currently you are appending str[j] which represents special character. Instead you should be appending string.charAt(i). Hope that helps.
stringToken.append(str[j]);
should be
stringToken.append(string.charAt(i));
Here is corrected version of your code, but there are better solutions for this problem.
public class StringTokens {
static String specialChars = new String(new char[]{' ', '!', ',', '?', '.', '_', '#'});
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("Enter only one line string");
} else {
display(args[0]);
}
}
public static void display(String string) {
StringBuilder stringToken = new StringBuilder();
stringToken.setLength(0);
for(char c : string.toCharArray()) {
if(!specialChars.contains(String.valueOf(c))) {
stringToken.append(c);
} else {
stringToken.append('\n');
}
}
System.out.println(stringToken);
}
}
public static void main(String[] args) {
String a=",!?#_."; //Add other special characters too
String test="Abc#xyz,2016!horrible_just?kidding"; //Make this as user input
for(char c : test.toCharArray()){
if(a.contains(c+""))
{
System.out.println(); //to avoid printing the special character and to print newline
}
else{
System.out.print(c);
}
}
}
you can run a simple loop and check ascii value of each character. If its something other than A-Z and a-z print newline skip the character and move on. Time complexity will be O(n) + no extra classes used.
String str = "Abc#xyz,2016!horrible_just?kidding";
char charArray[] = str.toCharArray();
boolean flag=true;;
for (int i = 0; i < charArray.length; i++) {
int temp2 = (int) charArray[i];
if (temp2 >= (int) 'A' && temp2 <= (int) 'Z') {
System.out.print(charArray[i]);
flag=true;
} else if (temp2 >= (int) 'a' && temp2 <= (int) 'z') {
System.out.print(charArray[i]);
flag=true;
} else {
if(flag){
System.out.println("");
flag=false;
}
}
}

Substring a string based on presence of a character

I have a string: LOAN,NEFT,TRAN. I want to substring the string based on getting a , during traversing the string. So I tried to first get a count for how many , are there. but not sure what function to user to get what I want. Also this should be dynamic, meaning I should be able to create as many substrings as required based on number of ,s. I tried the following code:
package try1;
public class StringTest {
public static void main(String[] args) {
String str="LOAN,NEFT,TRAN";
int strlen=str.length();
int count=0;
for(int i=0;i<strlen;i++)
{
if(str.contains("'"))
count++;
}
System.out.println(""+count);
for (int j=0;j<count;j++)
{
//code to create multiple substrings out of str
}
}
}
But I do not think contains() is the function I am looking for because value of count here is coming 0. What should I use?
Your code doesn't actually count the , characters because 1) contains doesn't take into account your loop variable 2) it's searching for ', not ,
Assuming you want to work at a low level rather than using high level functions like .split(), then I'd recommend the following.
for(char c : str.toCharArray()) {
if (c == ',') {
count++;
}
}
You can use split to get substrings directly:
String[] substrings = str.split(",");
Is this what you want as an output: (shown below)?
["LOAN", "NEFT", "TRAN"] // Array as an output
Or to just get the count of the splitting char, you can use the same line as above with this:
int count = substrings.length - 1;

Splitting string algorithm in Java

I'm trying to make the following algorithm work. What I want to do is split the given string into substrings consisting of either a series of numbers or an operator.
So for this string = "22+2", I would get an array in which [0]="22" [1]="+" and [2]="2".
This is what I have so far, but I get an index out of bounds exception:
public static void main(String[] args) {
String string = "114+034556-2";
int k,a,j;
k=0;a=0;j=0;
String[] subStrings= new String[string.length()];
while(k<string.length()){
a=k;
while(((int)string.charAt(k))<=57&&((int)string.charAt(k))>=48){
k++;}
subStrings[j]=String.valueOf(string.subSequence(a,k-1)); //exception here
j++;
subStrings[j]=String.valueOf(string.charAt(k));
j++;
}}
I would rather be told what's wrong with my reasoning than be offered an alternative, but of course I will appreciate any kind of help.
I'm deliberately not answering this question directly, because it looks like you're trying to figure out a solution yourself. I'm also assuming that you're purposefully not using the split or the indexOf functions, which would make this pretty trivial.
A few things I've noticed:
If your input string is long, you'd probably be better off working with a char array and stringbuilder, so you can avoid memory problems arising from immutable strings
Have you tried catching the exception, or printing out what the value of k is that causes your index out of bounds problem?
Have you thought through what happens when your string terminates? For instance, have you run this through a debugger when the input string is "454" or something similarly trivial?
You could use a regular expression to split the numbers from the operators using lookahead and lookbehind assertions
String equation = "22+2";
String[] tmp = equation.split("(?=[+\\-/])|(?<=[+\\-/])");
System.out.println(Arrays.toString(tmp));
If you're interested in the general problem of parsing, then I'd recommend thinking about it on a character-by-character level, and moving through a finite state machine with each new character. (Often you'll need a terminator character that cannot occur in the input--such as the \0 in C strings--but we can get around that.).
In this case, you might have the following states:
initial state
just parsed a number.
just parsed an operator.
The characters determine the transitions from state to state:
You start in state 1.
Numbers transition into state 2.
Operators transition into state 3.
The current state can be tracked with something like an enum, changing the state after each character is consumed.
With that setup, then you just need to loop over the input string and switch on the current state.
// this is pseudocode -- does not compile.
List<String> parse(String inputString) {
State state = INIT_STATE;
String curr = "";
List<String> subStrs = new ArrayList<String>();
for(Char c : inputString) {
State next;
if (isAnumber(c)) {
next = JUST_NUM;
} else {
next = JUST_OP;
}
if (state == next) {
// no state change, just add to accumulator:
acc = acc + c;
} else {
// state change, so save and reset the accumulator:
subStrs.add(acc);
acc = "";
}
// update the state
state = next;
}
return subStrs;
}
With a structure like that, you can more easily add new features / constructs by adding new states and updating the behavior depending on the current state and incoming character. For example, you could add a check to throw errors if letters appear in the string (and include offset locations, if you wanted to track that).
If your critera is simply "Anything that is not a number", then you can use some simple regex stuff if you dont mind working with parallel arrays -
String[] operands = string.split("\\D");\\split around anything that is NOT a number
char[] operators = string.replaceAll("\\d", "").toCharArray();\\replace all numbers with "" and turn into char array.
String input="22+2-3*212/21+23";
String number="";
String op="";
List<String> numbers=new ArrayList<String>();
List<String> operators=new ArrayList<String>();
for(int i=0;i<input.length();i++){
char c=input.charAt(i);
if(i==input.length()-1){
number+=String.valueOf(c);
numbers.add(number);
}else if(Character.isDigit(c)){
number+=String.valueOf(c);
}else{
if(c=='+' || c=='-' || c=='*' ||c=='/'){
op=String.valueOf(c);
operators.add(op);
numbers.add(number);
op="";
number="";
}
}
}
for(String x:numbers){
System.out.println("number="+x+",");
}
for(String x:operators){
System.out.println("operators="+x+",");
}
this will be the output
number=22,number=2,number=3,number=212,number=21,number=23,operator=+,operator=-,operator=*,operator=/,operator=+,

Categories

Resources