How to remove duplicate words in string without using array? - java

Is there any way we can remove duplicate words from a String without using Arrays?
For example, I have this sentence "this is java programming program",
and the output have to be "this java programming".
I see similar remove duplicate problems but all of them are using arrays.

well, in Java, Strings are actually objects wrappers for character arrays which primarily add immutability.
so, there is no actual way to not use arrays for your task.
even if you wrap your head around a solution which doesn't use any direct array creation in the code implementation, you will still be using arrays behind the scenes (if you want your solution to be optimal).

Remove duplicate words from a given string using simple way
package inffrd;
public class Q001
{
public static void removeduplicate(String input)
{
//convert the string to array by splitting it in words where space comes
String[] words=input.split(" ");
//put a for loop for outer comparison where words will start from "i" string
for(int i=0;i<words.length;i++)
{
//check if already duplicate word is replaced with null
if(words[i]!=null)
{
//put a for loop to compare outer words at i with inner word at j
for(int j =i+1;j<words.length;j++)
{
//if there is any duplicate word then make is Null
if(words[i].equals(words[j]))
{
words[j]=null;
}
}
}
}
//Print the output string where duplicate has been replaced with null
for(int k=0;k<words.length;k++)
{
//check if word is a null then don't print it
if(words[k]!=null)
{
System.out.print(words[k]+" ");
}
}
}
public static void main(String[] args)
{
String s1="i am dinesh i am kumar";
Q001.removeduplicate(s1);
}
}

Below is the updated code #Han
public class RemDup
{
public static void main ( String[] args )
{
String sentence = "this is java programming program progress";
int max_word_length = sentence.length()/2;
int min_word_length = 2;
while(max_word_length>=min_word_length)
{
int si = 0;
int ei = max_word_length;
while ( ei<sentence.length() )
{
int e=ei;
while ( e<sentence.length() )
{
int ind = sentence.indexOf ( sentence.substring ( si, ei ),e );
if ( ind!=-1 )
{
if(
sentence.substring(ind-1,ind).equals(" ")
&((ind+max_word_length)>=sentence.length()||
sentence.substring(ind+max_word_length,ind+max_word_length+1).equals(" "))
)
{
sentence = sentence.substring ( 0,ind ) +sentence.substring ( ind+max_word_length,sentence.length() );
}
e=ind+max_word_length;
}
else break;
}
si+=1;
ei+=1;
}
max_word_length--;
}
System.out.println(sentence);
}
}

Below code will help you :)
public class RemDup
{
public static void main ( String[] args )
{
String sentence = "this is java programming program";
int max_word_length = sentence.length()/2;
int min_word_length = 2;
while(max_word_length>=min_word_length)
{
int si = 0;
int ei = max_word_length;
while ( ei<sentence.length() )
{
int e=ei;
while ( e<sentence.length() )
{
int ind = sentence.indexOf ( sentence.substring ( si, ei ),e );
if ( ind!=-1 )
{
sentence = sentence.substring ( 0,ind ) +sentence.substring ( ind+max_word_length,sentence.length() );
e=ind+max_word_length;
}
else break;
}
si+=1;
ei+=1;
}
max_word_length--;
}
System.out.println(sentence);
}
}

Related

String reverse, wrong results

So my problem is about getting reversed String but only words which are longer or equals 5 characters.
So if we pass ("Hey fellow warriors") to the method we should get "Hey wollef sroirraw" in return. And my code gives me some weird results which are = "sroirraw fellow warriors ".
Here is my code, please give me some clue. The whitespace after last word shouldn't be returned but I don't know why it is.
public class PrimeChecker {
public String spinWords(String sentence) {
String[] tablica = sentence.split(" ");
for ( String x : tablica ) {
int y = 0;
if ( x.length() >= 5 ) {
StringBuilder p = new StringBuilder(x).reverse();
x = p.toString();
}
tablica[y] = x;
y++;
}
StringBuilder wynik = new StringBuilder();
for ( String z : tablica ) {
int y = 0;
tablica[y] = z;
wynik.append(tablica[y]);
if (tablica.length > 1 && y != tablica.length - 1 ) {
wynik.append(" ");
}
y++;
}
return wynik.toString();
}
}
Tester
public class PrimeCheckerTest {
public static void main(String[] args) {
PrimeChecker obiekt = new PrimeChecker();
System.out.println(obiekt.spinWords("Hey fellow warriors").toString());
}
}
First, I would prefer to split with \\s+ which matches one or more white-space characters. Second, I would use a lambda with Arrays.stream on the tokens I split. Then I would map each word, reversing every word with 5 or more characters. That can be done with a StringBuilder and reverse(). And since this method doesn't need any instance state we can make it static. Finally, join the words backs together with a Collector. Like,
public static String spinWords(String sentence) {
return Arrays.stream(sentence.split("\\s+"))
.map(s -> s.length() >= 5 ? new StringBuilder(s).reverse().toString() : s)
.collect(Collectors.joining(" "));
}
And to test it
public static void main(String[] args) {
System.out.println(spinWords("Hey fellow warriors"));
}
Which gives (as specified)
Hey wollef sroirraw
This code below will work. You have added y=0 inside the loop. That is unnecessary.
public class PrimeChecker {
public String spinWords(String sentence) {
String[] tablica = sentence.split(" ");
int y = 0;
for ( String x : tablica ) {
if ( x.length() >= 5 ) {
StringBuilder p = new StringBuilder(x).reverse();
x = p.toString();
}
tablica[y] = x;
y++;
}
StringBuilder wynik = new StringBuilder();
y=0;
for ( String z : tablica ) {
tablica[y] = z;
wynik.append(tablica[y]);
if (tablica.length > 1 && y != tablica.length - 1 ) {
wynik.append(" ");
}
y++;
}
return wynik.toString();
}
}
you need to define y out of for loop and before the second loop give it the value of zero , because you reset the value of y each loop .
You can do it in a simpler way:
public String spinWords(String sentence) {
String[] tablica = sentence.split(" ");
for (int i = 0; i < tablica.length; i++) {
if(tablica[i].length() >= 5) {
StringBuilder p = new StringBuilder(tablica[i]).reverse();
tablica[i] = p.toString();
}
}
StringBuilder builder = new StringBuilder();
for(String s : tablica) {
builder.append(s + " ");
}
String str = builder.toString();
return str;
}

How to print (but not return) a String recursively using Java?

I hate to abuse SO for homework but I'm in a pickle. Basically, my instructor wants me to do this:
Write a recursive method to print a String backwards.
The method header is: public void printBackwards1(String s)
The print statement must be before the recursive call.
The method should not alter or reverse the String, only print it backwards.
After that, they want me to do the same thing but have the print statement after the call.
I'm stumped. I already whipped up a normal-person recursive method:
public static String reverseString(String input) {
if(input.equals("")) {
return input;
}
else {
return(reverseString(input.substring(1)) + input.substring(0, 1));
}
}
But the print stuff has me scratching my head. Thanks in advance!
Just print whatever you are currently concatenating to the String :
public static void reverseString(String input) {
if(input.equals("")) {
return;
}
else {
reverseString(input.substring(1));
System.out.print(input.charAt(0));
}
}
or shorter :
public static void reverseString(String input) {
if(input.length() > 0) {
reverseString(input.substring(1));
System.out.print(input.charAt(0));
}
}
To answer the other alternative. You have to do the same basicly, despite that you need to keep in mind that you do print before doing the recursive call. Due to this you have to print the last letter before doing the recursive call, compared to the other solution from #Eran, where you print the first one.
private static void printBackwards2(String input) {
if (input.equals("")) {
return;
} else {
// Print the last char
System.out.print(input.substring(input.length()-1, input.length()));
// Recursive call without the last char by using substring
printBackwards2(input.substring(0,input.length()-1));
}
}
if I understand well you should print a "reverse" string using recursive call, if so, use for the first question:
public static void reverseString ( String input ) {
if ( input != null ) {
if ( input.length () <= 1 ) {
System.out.print ( input );
}else{
System.out.print ( input.charAt ( input.length ()-1 ));
reverseString ( input.substring ( 0, input.length ()-1) );
}
}
}
and for the second question
public static void reverseString ( String input ) {
if ( input != null ) {
if ( input.length () <= 1 ) {
System.out.print ( input );
}else{
reverseString ( input.substring ( 1, input.length ()) );
System.out.print ( input.charAt ( 0 ));
}
}
}

Java Palindrome program (1 error)

I asked a question yesterday about palindromes and Java:
Java Palindrome Program (am I on track)?
I've made some progress so far with all your help (thank you very much again). I just need help with one more thing before I can test the code out. I'm using Eclipse and I'm getting an error on one line (I'll also include the error as a comment in the code below). I keep getting a "Cannot invoke charAt(int) on the array type String[]".
Anyone know what is going on here? It's been a while since I used Java. Used it in C.S. One about 12 months ago, then I moved on to C++ in Data Structures, then Machine Code and Assembly Language in the next course. Here's the code (I've also included the error in a comment in the code). Thanks a lot:
public class Palindrome
{
public boolean isPalindrome( String theWord )
{
for ( int i = 0; i < theWord.length( ); i++ ) {
if ( theWord.charAt(i) != theWord.charAt (theWord.length() - i - 1) ) {
return false;
}
}
return true;
}
public static void main( String [] theWord )
{
int leftPointer = 0;
int rightPointer = theWord.length - 1;
for ( int i = 0; i < theWord.length / 2; i++ ) {
while (leftPointer >= rightPointer) {
if ( theWord.charAt(i) == theWord.charAt (theWord.length - i - 1) ) { // Error: Cannot invoke charAt(int) on the array type String[]
leftPointer++;
rightPointer--;
}
System.out.println(theWord);
}
}
}
}
You are trying to access a charAt() on an String[] (A String array of the arguments passed to your program), but you need to access it on a String. I world suggest something like:
if ( theWord[i].charAt(0) == theWord[theWord.length - i - 1].charAt (0) ) {
That might help you.
charAt(int index) is applied for a String, not a String array. Your program want to decide whether a string is a palindrome, like "abcba". Instead of check whether an array of Strings are all palindrome, right? For example {"abcba", "bbc", "aba"}.
In Java (as in C++) the program received parameter list, which is the array of Strings. Thus your class should looks like below:
public class Palindrome
{
public static boolean isPalindrome( String theWord )
{
for ( int i = 0; i < theWord.length( ); i++ ) {
if ( theWord.charAt(i) != theWord.charAt (theWord.length() - i - 1) ) {
return false;
}
}
return true;
}
public static void main( String [] args )
{
String theWord = args[0]; // first word passed to the program
boolean isPalindrom = Palindrome.isPalindrome(theWord);
System.out.println(theWord + " is" + ( isPalindrom ? "" : " NOT " ) + " a Palindrome." );
}
}
You forgot the () after invoking the method .length()
public static boolean isPalindrom(String value) {
if (value == null || value.length()==0 || value.length()==1) {
return true;
}
if(value.charAt(0)!=value.charAt(value.length()-1)) {
return false;
}
StringBuilder newValue =new StringBuilder(value);
newValue = new StringBuilder(newValue.substring(1, newValue.length()));
newValue = new StringBuilder(newValue.substring(0, newValue.length()-1));
return isPalindrom(newValue.toString());
}
try this simple recursive method.
import java.util.*;
public class MyClass {
public static void main(String args[]) {
String str = "pappap";
String sp = str.toLowerCase();
char[] ch = sp.toCharArray();
int len = ch.length;
int lastIndex = ch.length-1;
int count = 1;
int first = 0;
int last = sp.length()-1;
for(; first < last ;){
if(ch[first] == ch[last] ){
first= first+1;
last= last-1;
}
else{
count = 0;
break;
}
}
String result = (count == 1) ? "Palindrome" : "Not a palindrome " ;
System.out.println(result);
}
}

how to search for keywords in strings

I need to do some keywords search and print if true.
works fine if i am comparing in order. but i want to
compare the following cases and expect them to be true.
do some java programming = true
some java = true
do programming = true
and finally most importantly
programming java = true
programming java some do = true
I need to return true for all the cases mentioned above but so far it only works for case 1 and 2
public class Examples {
public static void main(String[] args) {
String[] given = new String[20];
given[0] = ("do some java programming");
given[1] = ("do some grocery shopping");
given[2] = ("play soccer at the west field");
String input = new String();
Scanner userInput = new Scanner(System.in);
System.out.println("Enter the string to compare");
input[0] = userInput.nextLine();
for (int i=0; i <20; i++){
if(given[i].contains(input))
{
System.out.println(given[i]);
}
else
{
//do nothing
}
}
}
}
Outline of one way to solve this:
Each string in given should be converted to a Set<String> that is a set of all the words in the string. Use split() on each string to get the words, then go through the list of words and add each word to the Set.
For each input string, use split() to split it into words, then create any kind of collection (a Set<String> will work, but creating a List<String> by using Arrays.asList works too.
You can then see if the collection of words from the input is a subset of the set of words in each given string by using a Set's containsAll method.
(Note that you'll have to make sure the input string isn't the empty set first. Also, if the input string has more than one occurrence of any word, this approach won't catch that, without some extra logic.)
For this Regex will be your friend.
Here's some working code to play with:
String[] matches = input[0].split(" ");
for (int i=0; i <3; i++){
for(String s: matches){
if(given[i].contains(s))
System.out.println(given[i]);
break;
}
}
}
Split the given lines and store it in a List.
Again split the input line and compare word by word.
Below is the code snippet
public class StringCompare
{
public static final String delimiter = " ";
public static void main( String[] args )
{
String[] given = new String[20];
given[ 0 ] = ( "do some java programming" );
given[ 1 ] = ( "do some grocery shopping" );
given[ 2 ] = ( "play soccer at the west field" );
List< List< String >> listLineAsWords = new ArrayList< List< String >>();
//split each line and store it as list.
for ( String line : given )
{
if ( line == null )
break;
listLineAsWords.add( Arrays.asList( line.split( delimiter ) ) );
}
//Write your own logic to get the input line
String inputLine = "programming java";
if ( compareLine( inputLine, listLineAsWords ) )
System.out.println( "The input line is part of given lines" );
}
private static boolean compareLine( String inputLine, List< List< String >> listLineAsWords )
{
if ( inputLine == null )
return false;
List< String > words = Arrays.asList( inputLine.split( delimiter ) );
for ( List< String > listOfWords : listLineAsWords )
{
boolean isPartOfLine = true;
for ( String word : words )
{
if ( !listOfWords.contains( word ) )
{
isPartOfLine = false;
break;
}
}
if(isPartOfLine)
return true;
}
return false;
}
}
Your code is almost right, yet it needs some changes
First, since in your sample code you have 3 case, it is best to define your given array length 3.
String[] given = new String[3];
Note: for more cases, you can define bigger array length; for example, if you will add other 2 cases, your array length is 5
For all reference types, the default value is null if you have array length more than you need.
read more about it here
Second, in your if statement, you want to check if input contains given element of array or not
if (input.contains(given[i])) {
code:
String[] given = new String[3];
given[0] = ("do some java programming");
given[1] = ("do some grocery shopping");
given[2] = ("play soccer at the west field");
Scanner userInput = new Scanner(System.in);
System.out.println("Enter the string to compare");
String input = userInput.nextLine();
for (int i = 0; i < given.length; i++) {
if (input.contains(given[i])) {
System.out.println(given[i]);
} else {
// System.out.println("do nothing");
}
}
output:
Modify as below assuming everything else is fine
//here initialize 'given' array
//get the user input in a string that is 'input[0]' in your case
int count = 0;
for (String s : given) {
if (s != null && s.matches(input[0])) {
//it matches and print it
} else {
//either it's not a match or the 'given' array has a null at this index
}
count++;
}
I must say, get the user input in a string. I don't understand why you have it in input array.

Translating multiple characters into one

I need help converting Morse Code to English. I have already written and tested the code for translating English to Morse. My main problem is having all the characters in the Morse code together before translating it to an English character if that makes sense.
Example: "." translates to E and ... translates to S, but I don't want the translation to start until it reaches ...
Few Rules
-Spaces are used to separate Morse Letters
-| is used as an delimiter to separate words
-Cant use an hashmap :(
Here is my code
import java.util.Arrays;
import javax.swing.JOptionPane;
public class test3
{
public static void main ( String [] args )
{
String s1 = "Morse";
// Decide whether Morse code or English
String decide = JOptionPane.showInputDialog("Enter 'English' for Morse to English code translation and 'Morse' for English to Morse code translation. Pay attention to Caps.");
// Enter String & decide whether to convert to Morse or English
String phrase = JOptionPane.showInputDialog("Enter the words you wish to translate.");
if ( decide.equals( s1 ))
toMorse( phrase );
else
toEnglish( phrase );
}
// Translate to Morse
public static void toMorse( String preTranslation )
{
String[] english = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","1","2","3","4","5","6","7","8","9","0"};
String[] morse = {".-","-...","-.-.","-..",".","..-.","--.","....","..", ".---",
"-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-",
"...-",".--","-..-","-.--","--..",".----","..---","...--","....-",".....","-....","--...","---..","----.","-----"};
// Remove uppercase
String preTrans = preTranslation.toLowerCase();
// Deletes spaces
String phraseWithDelimiter = preTrans.replace( " ", "|");
String[] translation = new String[phraseWithDelimiter.length()];
String[] delimiter = {"|"};
// Translate
for ( int arrayVar = 0, transArrayVar = 0, subStringVarB = 0, subStringVarE = 1; transArrayVar < phraseWithDelimiter.length();)
{
if( phraseWithDelimiter.substring(subStringVarB, subStringVarE).equals( delimiter[0] ) )
{
translation[transArrayVar] = delimiter[0];
transArrayVar++;
subStringVarB++;
subStringVarE++;
}
else if ( phraseWithDelimiter.substring(subStringVarB, subStringVarE).equals( english[arrayVar] ) )
{
translation[transArrayVar] = morse[arrayVar];
transArrayVar++;
subStringVarB++;
subStringVarE++;
arrayVar = 0;
}
else
{
arrayVar++;
if ( arrayVar == 35 )
{
arrayVar = 0;
subStringVarB++;
subStringVarE++;
transArrayVar++;
}
}
}
String morseSeparator = new String( " " );
arrayToString ( translation, morseSeparator );
}
//Convert array to string and print translation
public static void arrayToString(String[] trans, String separator)
{
String result = "";
if (trans.length > 0)
{
result = trans[0]; // start with the first element
for (int i = 1; i < trans.length; i++)
result = result + separator + trans[i];
}
System.out.println( result );
}
// unfinished
public static void toEnglish( String preTranslation)
{
}
I was thinking about making a for statement and assigning every character of the Morse code to a new string until I reach a white space and then using that to test but I'm unsure about how to do that.
Any help is appreciated thanks!
Create a regular expression containing all the Morse code sequences in order from longest to shortest.
Pattern.compile("----\\.|-----|---\\.\\.|...")
and then just match that repeatedly against a string to get the longest valid Morse code sequence.
Alternatively, you can use a parser compiler like JavaCC.
SKIP : { " " }
TOKEN : { < A : "-." > }
TOKEN : { < B : "-..." > }
TOKEN : { < C : "-.-." > }
...
String translate() :
{ StringBuilder sb; }
{
{ sb = new StringBuilder(); }
(
letter(sb)
)*
<EOF>
{ return sb.toString(); }
}
void letter(StringBuilder sb) :
{}
{
( <A>
{ sb.append('a'); }
| <B>
{ sb.append('b'); }
| <C>
{ sb.append('c'); }
...
)
}
For translating the text you might try and split it on word delimiters first, then on character limiters. Then process the words one by one. Similar to this:
String morseInput = //whatever, only delimiters or morse characters
String[] words = morseInput.split("-|");
for( String word : words ) {
String[] characters = word.split("\\s");
for( String c : characters ) {
//look up the english character for c - I'd use a map here
}
}
A few notes:
I omitted checks for empty strings and null for brevity
I also left out any code to build the final translation string, that's an excercise for you
I'd use a Map<String, String> for the lookup, if that's not allowed, look up the index of the character in the source array and then get the translation at that index from the translation array

Categories