Removing duplicate chars from a string passed as a parameter - java

I am a little confused how to approach this problem. The userKeyword is passed as a parameter from a previous section of the code. My task is to remove any duplicate chars from the inputted keyword(whatever it is). We have just finished while loops in class so some hints regarding these would be appreciated.
private String removeDuplicates(String userKeyword){
String first = userKeyword;
int i = 0;
while(i < first.length())
{
if (second.indexOf(first.charAt(i)) > -1){
}
i++;
return "";
Here's an update of what I have tried so far - sorry about that.

This is the perfect place to use java.util.Set, a construct which is designed to hold unique elements. By trying to add each word to a set, you can check if you've seen it before, like so:
static String removeDuplicates(final String str)
{
final Set<String> uniqueWords = new HashSet<>();
final String[] words = str.split(" ");
final StringBuilder newSentence = new StringBuilder();
for(int i = 0; i < words.length; i++)
{
if(uniqueWords.add(words[i]))
{
//Word is unique
newSentence.append(words[i]);
if((i + 1) < words.length)
{
//Add the space back in
newSentence.append(" ");
}
}
}
return newSentence.toString();
}
public static void main(String[] args)
{
final String str = "Words words words I love words words WORDS!";
System.out.println(removeDuplicates(str)); //Words words I love WORDS!
}

Have a look at this answer.
You might not understand this, but it does the job (it cleverly uses a HashSet that doesn't allow duplicate values).
I think your teacher might be looking for a solution using loops however - take a look at William Morisson's answer for this.
Good luck!

For future reference, StackOverflow normally requires you to post what you have, and ask for suggestions for improvement.
As its not an active day, and I am bored I've done this for you. This code is pretty efficient and makes use of no advanced data structures. I did this so you could more easily understand it.
Please do try to understand what I'm doing. Learning is what StackOverflow is for.
I've added comments in the code to assist you in learning.
private String removeDuplicates(String keyword){
//stores whether a character has been encountered before
//a hashset would likely use less memory.
boolean[] usedValues = new boolean[Character.MAX_VALUE];
//Look into using a StringBuilder. Using += operator with strings
//is potentially wasteful.
String output = "";
//looping over every character in the keyword...
for(int i=0; i<keyword.length(); i++){
char charAt = keyword.charAt(i);
//characters are just numbers. if the value in usedValues array
//is true for this char's number, we've seen this char.
boolean shouldRemove = usedValues[charAt];
if(!shouldRemove){
output += charAt;
//now this character has been used in output. Mark that in
//usedValues array
usedValues[charAt] = true;
}
}
return output;
}
Example:
//output will be the alphabet.
System.out.println(removeDuplicates(
"aaaabcdefghijklmnopqrssssssstuvwxyyyyxyyyz"));

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 loop through my String array and find the amount of occurrences of multiple strings?

I have an array in my modularized program and i am trying to find the amount of times Strings appear in the array. I cannot post my code as it violates my schools honor code, just looking some help....I cannot use any classes besides JOptionPane. Java code.
i am not sure cause you dont post your code but i know you want that :
String[] yourArray = {"test", "1234","test"};
String yourStringTest = "test";
int occurence = 0;
for(int i = 0; i < yourArray.length;i++) {
if(yourStringTest.equalsIgnoreCase(yourArray[i])) {
occurence++;
}
}
System.out.println("the string "+yourStringTest+" appear :"+occurence);

How to create a loop for

I need to create a loop that adds "o" after each consonant
I am going to walk you through what I corrected and changed in your code to make it work in order to make it quick and easy for you to comprehend why your code doesn't work and why my answer fixes it.
The mistakes you made are basic ones and frankly you shouldn't have to much of a hard time correcting them yourself if you would use a debugger that walks you step by step in how your code works. You should look on how to use a debugger (for example the debugger used in Eclipse, hopefully you are using an IDE to make your life easier).
Firstly, when you are looking for a consonant in your code, you are only walking through the half of it because of your condition for(int x = 0; x<20; x++) since your string holding the consonants if of a length of 40 characters. This means you are missing consonants like the letter s.
Then you are correctly the consonants you find according to your Swedish language game. But you are never handling characters that are not of these found consonants. You should make a case where you handle these "non consonant" letters, may they be vowels or any kind of character (like punctuation marks and so on). I am fixing this with the use of a simple boolean here.
Keep in mind that my goal here is to change your code as little as I can, thus I went for adding a boolean to handle your cases (checking the presence of a consonant). There are, obviously, many other ways to implement what you are trying to do.
Here come the changes you should add to your code:
/*This comes after your print "På rövarspråk:"*/
boolean isConsonant = false; //Boolean to check wether there is a consonant or not
for(int i = 0; i<length; i++) {
//You didn't go through the whole consonants list you made with your prevision condition
for(int x = 0; x<consonants.length; x++){
if(array[i] == consonants[x])
{
isConsonant = true; //Set the boolean accordingly
String add = array[i]+"o"+array[i];
slang = slang + add;
break;
}
}
if(!isConsonant){ //If we don't have a consonant, add the char to the result string
slang += array[i];
}
isConsonant = false; //Reset the boolean for the next character
}
/*Here you can print the result (slang) if you want, as you did*/
so the idea is to dublicate consonants and put "o" between them, like t becomes tot, s becomes sos. Vocals are just copied. So you need a method that tells you if a given character is a vocal or consonant to base your decision on that.
public static boolean isConsonant(char inputChar){
final String consonantsx = "bBcCdDfFgGhHjJkKlLmMnNpPqQrRsStTvVwWxXzZ";
char consonants[] = consonantsx.toCharArray(); // String to charr
for(int i=0; i < consonants.length;i++){
if(inputChar == consonants[i]){ //note that in Strings u use the equals method instead of "=="
return true;
}
}
return false;
}
Given this method you can use it in the "translator method".
public String rovarSpraket(String normalString) {
char[] array = normalString.toCharArray(); // Input to a char array
System.out.println("På rövarspråk:");
String slang = "";
for (int i = 0; i < normalString.length(); i++) {
String add = "" + array[i];
if(Goran.isConsonant(array[i])){
add += "o" + array[i];
}
slang += add;
}
return slang;
}
This translates stubborn to sostotubobboborornon like in the wikipedia article https://en.wikipedia.org/wiki/R%C3%B6varspr%C3%A5ket.

Having problems with a search method between Arrays and Array lists

OK so I'm trying to design a simple program that checks to see if a substring of length 4 characters is within all initial strings. Here is my code as follows:
public class StringSearch{
private String[] s1Array = {"A","C","T","G","A","C","G","C","A","G"};
private String[] s2Array = {"T","C","A","C","A","A","C","G","G","G"};
private String[] s3Array = {"G","A","G","T","C","C","A","G","T","T"};
//{for (int i = 0; i < s1Array.length; i++){
// System.out.print(s1Array[i]);
//}}//check if Array loaded correctly
/**
* This is the search method.
*
* #param length length of sub string to search
* #param count counter for search engine
* #param i for-loop counter
* #return subStr returns strings of length = 4 that are found in all 3 input strings with at most
* one mismatched position.
*/
public String Search()
{
int length = 4;
int count = 0;
int i = 0;
ArrayList<StringSearch> subStr = new ArrayList<StringSearch>();
//String[] subStr = new String[4];
do
{
for (i = count; i < length; i++){
subStr.add(s1Array[i]); // cant find .add method???
count = count + 1;
}
if (s2Array.contains(subStr) && s3Array.contains(subStr)){ //can't find .contains method???
System.out.println(subStr + "is in all 3 lists.");
}
if (count = s1Array.length){
System.out.println("Task complete.");
}
else{
count = count - length;
count = count + 1;
}
}while (count <= s1Array.length);
}
}
For some reason, Java cannot seem to find the .add or .contains methods and I have no idea why. So my approach was to turn the initial Strings each into an array (since the assignment specified each string would be exactly N elements long, in this case N = 10) where 1 letter would be 1 element. The next thing I did was set up a for loop that would scan s1Array and add the first 4 elements to an ArrayList subStr which is used to search s2Array and s3Array. Here is where .add isn't a valid method, for whatever reason. Commenting that out and compiling again, I also ran into an issue with the .contains method not being a valid method. Why won't this work? What am I missing? Logically, it seems to make sense but I guess maybe I'm missing something in the syntax? Help would be appreciated, as I'm a Java novice.
There are lots of errors and misunderstandings here.
Let's start with #1
private String[] s1Array = {"A","C","T","G","A","C","G","C","A","G"};
Making an array of strings is just silly, you should either use a single string or an array of characters.
private String s1 = "ACTGACGCAG";
Or
private char[] s1Array = {'A','C','T','G','A','C','G','C','A','G'};
Now #2
ArrayList<StringSearch> subStr = new ArrayList<StringSearch>();
This means you are trying to make an ArrayList that contains objects of type StringSearch. StringSearch is a class that contains your three arrays and your Search function so I don't think this is what you want.
If you wanted to make a list of 3 strings you might do something like this:
ArrayList<String> stringList = new ArrayList<String>();
stringList.add(s1);
stringList.add(s2);
stringList.add(s3);
Now say you defined s1, s2 and s3 as strings you can do something like this.
for(int i = 0; i <= s1.length() - 4; i++)
{
String subStr = s1.substring(i, i + 4);
if(s2.contains(subStr) && s3.contains(subStr))
{
System.out.println(subStr + " is in all 3 lists.");
}
}
System.out.println("Task Complete.");
The above code should achieve what it looks like you are trying to do. However, it should be noted that this isn't the most efficient way, just a way, of doing it. You should start with some more basic concepts judging by the code you have so far.
After declaring subStr as ArrayList you can call add or contains only with StringSearch objects as parameters.
Instead of:
ArrayList<StringSearch> subStr = new ArrayList<StringSearch>();
Replace it with:
String subStr = "";
And within the for loop to get the first 4 letters in s1 to be in its own string (subStr) add the line:
subStr += s1Array[i];
Also, s1Array is a String array, and not a String. The .contains method is a method that belongs to String variables, so for eg. the way you have it implemented, you can say s1Array[i].contains. But you cannot say s1Array.contains. If you change your String arrays to Strings and edit your code to suit, everything should work the way you expect it to work.
First of all you need to educate yourself on the concept of Java generics.
The most basic thing about generics is that once you declare a collection, here it is the arraylist, as you can only add objects of StringSearch.
Second of all, logically what you can do is to implement an algorithm called
Longest Common Subsequence. Check in pairs whether the longest subsequeces are 4 or not on the arrays.

How to print several strings backwards in Java

I am trying to take a file full of strings, read it, then print out a few things:
The string
The string backwards AND uppercase
The string length
There are a few more things, however I haven't even gotten to that point and do not want to ask anyone to write the code entirely for me. After messing around with it for a while, I have it almost completed (I believe, save for a few areas).
The piece that is tripping me up is the backwards word. We are required to put our output neatly into columns using prinf, but I cannot do this if I read each char at a time. So I tried setting a String backwardsWord = ""; and adding each character.
This is the piece that is tripping me up:
for(int i = upperCaseWord.length() - 1; i >= 0; i--)
{
backwardsWord += (upperCaseWord.charAt(i) + "");
}
My issue is that when I print it, the first word works properly. However, each word after that is added to the previous word.
For example: if I am printing cat, dog, and rat backwards, it shows
TAC
TACGOD
TACGODTAR
I obviously want it to read
TAC
GOD
TAR
Any help would be appreciated.
It looks like your variable backwardsWord is always appending a character without being reset between words. The simplest fix is to clear the backwardsWord just before your loop by setting it to empty string.
backwardsWord = ""; //Clear any existing characters from backwardsWord
for(int i = upperCaseWord.length() - 1; i >= 0; i--)
{
backwardsWord += (upperCaseWord.charAt(i) + "");
}
If you are building up a String one character at a time you will be using a lot of memory because Java Strings are immutable.
To do this more efficiently use a StringBuilder instead. This is made for building up characters like what you are doing. Once you have finished you can use the toString method to get the String out.
StringBuilder builder = new StringBuilder(); //Creates the String builder for storing the characters
for(int i = upperCaseWord.length() - 1; i >= 0; i--)
{
builder.append(upperCaseWord.charAt(i)); //Append the characters one at a time
}
backwardsWord = builder.toString(); //Store the finished string in your existing variable
This has the added benefit of resetting the backwardsWord each time.
Finally, since your goal is to get the String in reverse we can actually do it without a loop at all as shown in this answer
backwardsWord = new StringBuilder(upperCaseWord).reverse().toString()
This creates a new StringBuilder with the characters from upperCaseWord, reverses the characters then stores the final string in backwardsWord
Where are you declaring the String backwardsWord?
If you don't clear it between words then the memory space allocated to that string will still contain the previously added characters.
Make sure you are tossing in a backwardsWord = ""; in between words to reset it's value and that should fix your problem.
Without seeing more of your code I can't tell you exactly where to put it.
This should do the job ->
class ReverseWordsInString{
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));
}
public static void main(String[] args){
String st = "Cat Dog Rat";
String r = "";
for (String word : st.split(" "))
r += " "+ reverse(word.toUpperCase());
System.out.println("Reversed words in the given string: "+r.trim());
}
}

Categories

Resources