Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I've been asked to write a code that adds elements to an array with a few conditions. I've searched all over StackOverflow to find out how to find an element in an array but all give me errors, so I'm guessing it's something wrong with my code and I can't figure out what. Any help is appreciated.
public class WordList
{
String [] words;
int count = 0;
int max = 2;
WordList()
{
words = new String[max];
this.words = words;
this.count = count;
}
public static void main (String[] args)
{
WordList w1 = new WordList();
System.out.println(w1.addWord("Dog"));
System.out.println(w1.addWord("Cat"));
System.out.println(w1.addWord("Fish"));
}
public int addWord(String newWord)
{
for(int i = 0; i < words.length; i++)
{
if(words.contains(newWord) == false && words.length < max)
{
words[i] = newWord;
}
else if(words.contains(newWord) == false && words.length == max)
{
max *= 2;
words[i] = newWord;
}
count = i + 1;
}
return count;
}
I think you could use Set instead of array.
public class WordList {
private final Set<String> words = new HashSet<>();
public int addWord(String word) {
if (word != null)
words.add(word);
return words.size();
}
public static void main(String[] args) {
WordList w1 = new WordList();
System.out.println(w1.addWord("Dog"));
System.out.println(w1.addWord("Cat"));
System.out.println(w1.addWord("Fish"));
}
}
I think this is what you're trying to do. Regular arrays dont have an indexOf or contains method so you need to use Arrays (make sure you import it too)
public int addWord(String newWord)
{
List <String> myList = Arrays.asList(words);
for(int i = 0; i < words.length; i++)
{
if(myList.indexOf(newWord) == -1 && words.length < max)
{
words[i] = newWord;
}
else if(myList.indexOf(newWord) == -1 && words.length == max)
{
max *= 2;
words[i] = newWord;
}
count = i + 1;
}
return count;
}
In Any way you'll need to write your own method to find it. It you are not limited with memory - you can convert array to List and use .contains() method.
Arrays.asList(words).contains(newWord);
Otherwise you may use stream to find the element.
Arrays.stream(words).anyMatch(newWord::equals);
I think you are looking for a solution something like this, but this is using ArrayList and not Array. Arrays do not have default contains method and you would need to implement your own method.
import java.util.ArrayList;
import java.util.List;
public class WordList {
private static List<String> words = new ArrayList<>();
public void addWord(String word) {
if (!words.contains(word)) {
words.add(word);
}
}
public static List<String> getWords() {
return words;
}
public static void main(String... args) {
WordList instance = new WordList();
instance.addWord("Dog");
instance.addWord("Cat");
instance.addWord("Fish");
System.out.println(instance.getWords());
}
}
Error was in words.contains(newWord)
cannot find symbol symbol: method contains(String) location:
variable words of type String[]
It could resolve by change code -
Arrays.asList(words).contains(newWord) instead of words.contains(newWord).
Remember you will need to import java.util.Arrays
Full code -
import java.util.Arrays;
/**
*
* #author pronet
*/
public class WordList
{
String [] words;
int count = 0;
int max = 2;
WordList()
{
words = new String[max];
this.words = words;
this.count = count;
}
public static void main (String[] args)
{
WordList w1 = new WordList();
System.out.println(w1.addWord("Dog"));
System.out.println(w1.addWord("Cat"));
System.out.println(w1.addWord("Fish"));
}
public int addWord(String newWord)
{
for(int i = 0; i < words.length; i++)
{
if(Arrays.asList( words ).contains(newWord) == false && words.length < max)
{
words[i] = newWord;
}
else if(Arrays.asList( words ).contains(newWord) == false && words.length == max)
{
max *= 2;
words[i] = newWord;
}
count = i + 1;
}
return count;
}
}
Hope it could help you.
import java.util.HashSet;
import java.util.Set;
public class WordList {
private final Set<String> words = new HashSet<>();
public static void main(String[] args) {
WordList w1 = new WordList();
System.out.println(w1.addWord("Dog"));
System.out.println(w1.addWord("Cat"));
System.out.println(w1.addWord("Fish"));
}
public int addWord(String word) {
words.add(word);
return words.size();
}
}
Related
I am currently trying to solve this challenge on hackerrank Tries - Contacts
And my algorithm fails for only one test case. Test case #1. Can any one share any insight into what I need to change in order to pass this test case. I am using a TrieNode class that contains a hashmap of its children nodes. I also store the size of each node to deonte how many words it contains.
Test case #1 is as follows:
add s
add ss
add sss
add ssss
add sssss
find s
find ss
find sss
find ssss
find sssss
find ssssss
The code is as follows:
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
TrieNode root;
class TrieNode{
Map<Character, TrieNode> children = new HashMap<Character, TrieNode>();
int size=0;
}
public Solution(){
root = new TrieNode();
}
public void addWord(String word){
TrieNode current = root;
for(int i=0;i<word.length();i++){
char c = word.charAt(i);
if(!current.children.containsKey(c)){
//create a new node
TrieNode temp = new TrieNode();
//add the word to the current node's children
current.children.put(c, temp);
current.size++;
current = temp;
}
else{
current.size++;
current = current.children.get(c);
}
}
}
public void prefixSearch(String letters){
TrieNode current = root;
boolean sequenceExists = true;
for(int i=0; i<letters.length();i++){
char c = letters.charAt(i);
if(current.children.containsKey(c)){
if(i == letters.length()-1){
System.out.println(current.size);
break;
}
else{
current = current.children.get(c);
}
}
else{
System.out.println(0);
break;
}
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
Solution sol = new Solution();
for(int a0 = 0; a0 < n; a0++){
String op = in.next();
String contact = in.next();
if(op.equals("add")){
if(contact.length() >=1 && contact.length() <=21)
sol.addWord(contact);
}
else if(op.equals("find")){
if(contact.length() >=1 && contact.length() <=21)
sol.prefixSearch(contact);
}
else{
//do nothing
}
}
}
}
When you add words to your Trie you increment count for all nodes, except the last one. This is quite common and hard to notice kind of error called off-by-one https://en.wikipedia.org/wiki/Off-by-one_error
add this line once again at the end of addWord method (after the loop):
current.size++;
Your code passed test case 0 because this particular bug in your code doesn't show up when you look up a prefix like hac-kerrank, but does show up when you look up for complete word including the last character like hackerrank, or sssss
I have this solution, except test case 0, 1 & 5 all others are timing out. Here is my implementation in java 8. Where should I improve my code to pass all the test cases
public class Contacts {
static Map<String, String> contactMap = new HashMap<>();
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
for(int a0 = 0; a0 < n; a0++){
String op = in.next();
String contact = in.next();
if(op.equalsIgnoreCase("add")) {
addOrFind(contact, op);
} else {
addOrFind(contact, op);
}
}
}
public static void addOrFind(String name, String type) {
if(type.equalsIgnoreCase("add")) {
contactMap.put(name, name);
} else {
long count = contactMap.entrySet().stream()
.filter(p->p.getKey().contains(name)).count();
System.out.println(count);
}
}
}
If you will checkout:enter link description here
And also use their test case of:
4
add hack
add hackerrank
find hac
find hak
It will compile.
// from his website at https://github.com/RodneyShag/HackerRank_solutions/blob/master/Data%20Structures/Trie/Contacts/Solution.java
import java.util.Scanner;
import java.util.HashMap;
public class Solution {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
Trie trie = new Trie();
for (int i = 0; i < n; i++) {
String operation = scan.next();
String contact = scan.next();
if (operation.equals("add")) {
trie.add(contact);
} else if (operation.equals("find")) {
System.out.println(trie.find(contact));
}
}
scan.close();
}
}
/* Based loosely on tutorial video in this problem */
class TrieNode {
private HashMap<Character, TrieNode> children = new HashMap<>();
public int size = 0; // this was the main trick to decrease runtime to pass tests.
public void putChildIfAbsent(char ch) {
children.putIfAbsent(ch, new TrieNode());
}
public TrieNode getChild(char ch) {
return children.get(ch);
}
}
class Trie {
TrieNode root = new TrieNode();
Trie(){} // default constructor
Trie(String[] words) {
for (String word : words) {
add(word);
}
}
public void add(String str) {
TrieNode curr = root;
for (int i = 0; i < str.length(); i++) {
Character ch = str.charAt(i);
curr.putChildIfAbsent(ch);
curr = curr.getChild(ch);
curr.size++;
}
}
public int find(String prefix) {
TrieNode curr = root;
/* Traverse down tree to end of our prefix */
for (int i = 0; i < prefix.length(); i++) {
Character ch = prefix.charAt(i);
curr = curr.getChild(ch);
if (curr == null) {
return 0;
}
}
return curr.size;
}
}
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
My user input is
\home\me\cs1
\usr\share
\var\log
\usr\local\jdk1.6.0\jre\lib
and I need to sort these pathnames so that the output is in the correct lexographic order. However they are first sorted by length which is the number of slashes in each string. The path names are stored in an arraylist of strings. I attempting to do this without the use of collections,comparator or arrays. Would this be possible with the use of ArrayList?
the output should be:
\usr\share
\var\log
\home\me\cs1
\usr\local\jdk1.6.0\jre\lib
This is my code so far:
import java.util.ArrayList;
import java.util.Scanner;
public class FileName
{
private ArrayList<String> pathNames;
public FileName()
{
pathNames = new ArrayList<String>();
}
public void printPaths()
{
for(int i = 0; i < pathNames.size(); i++)
{
System.out.println(pathNames.get(i));
}
}
public int pathLength(String path)
{
int count = 0;
String slash = "\\";
for(int i = 0; i < path.length(); i++)
{
if(path.substring(i,i + 1).equals(slash))
{
count++;
}
}
return count;
}
public void sort()
{
pathNames = mergeSort(pathNames);
}
public ArrayList<String> mergeSort(ArrayList<String> paths)
{
if(paths.size() == 1)
{
return paths;
}
else
{
ArrayList<String> left = new ArrayList<String>();
ArrayList<String> right = new ArrayList<String>();
int middle = paths.size() / 2;
for(int i = 0; i < middle; i++)
{
left.add(paths.get(i));
}
for(int i = middle; i < paths.size(); i++)
{
right.add(paths.get(i));
}
right = mergeSort(left);
left = mergeSort(left);
merge(left, right, paths);
}
return paths;
}
public void merge(ArrayList<String> left, ArrayList<String> right, ArrayList<String> paths)
{
int leftNum = 0;
int rightNum = 0;
int pathsNum = 0;
while (leftNum < left.size() && rightNum < right.size())
{
if ((left.get(leftNum).compareTo(right.get(rightNum)))<0)
{
paths.set(pathsNum, left.get(leftNum));
leftNum++;
}
else
{
paths.set(pathsNum, right.get(rightNum));
rightNum++;
}
pathsNum++;
}
ArrayList<String>rest;
int restNum;
if (leftNum >= left.size())
{
rest = right;
restNum = rightNum;
}
else
{
rest = left;
restNum = leftNum;
}
for (int i = restNum; i < rest.size(); i++)
{
paths.set(pathsNum, rest.get(i));
pathsNum++;
}
}
public void readInput()
{
Scanner input = new Scanner(System.in);
System.out.println("Please enter a list of path names.(press enter after each path name, and type \"stop\" once you are finished.");
String termination = "stop";
String in = input.nextLine();
boolean reading = true;
while(reading)
{
pathNames.add(in);
if(in.equals(termination))
{
reading = false;
return;
}
in = input.nextLine();
}
}
}
This is my main method.
public class FileNamePrgm
{
public static void main(String [] args)
{
FileName paths = new FileName();
paths.readInput();
paths.sort();
}
}
You have a typo:
right = mergeSort(left);
Should be
right = mergeSort(right);
Also you need to add in = input.nextLine(); once more inside the while loop. Currently you are reading only one line from the input and checking it over and over again.
Given an array of strings, return another array containing all of its longest strings.
For (String [] x = {"serm", "aa", "sazi", "vcd", "aba","kart"};)
output will be
{"serm", "sazi" , "kart"}.
The following code is wrong, What can I do to fix it.
public class Tester {
public static void main(String[] args) {
Tester all = new Tester();
String [] x = {"serm", "aa", "sazi", "vcd", "aba","kart"};
String [] y = all.allLongestStrings(x);
System.out.println(y);
}
String[] allLongestStrings(String[] input) {
ArrayList<String> answer = new ArrayList<String>(
Arrays.asList(input[0]));
for (int i = 1; i < input.length; i++) {
if (input[i].length() == answer.get(0).length()) {
answer.add(input[i]);
}
if (input[i].length() > answer.get(0).length()) {
answer.add(input[i]);
}
}
return answer.toArray(new String[0]);
}
}
I will give you solution, but as it homework, it will be only sudo code
problem with your solution is, you are not finging longest strings, but strings same size or bigger than size of first element
let helper = []
let maxLength = 0;
for each string in array
if (len(string) >maxLength){
maxLength = len(string);
clear(helper)
}
if (len(string) == maxLength)
helper.add(string)
}
return helper;
You can try below code
private static String[] solution(String[] inputArray) {
int longestStrSize = 0;
List<String> longestStringList = new ArrayList<>();
for (int i = 0; i < inputArray.length; i++) {
if (inputArray[i] != null) {
if (longestStrSize <= inputArray[i].length()) {
longestStrSize = inputArray[i].length();
longestStringList.add(inputArray[i]);
}
}
}
final int i = longestStrSize;
return longestStringList.stream().filter(x -> x.length() >= i).collect(Collectors.toList()).stream()
.toArray(String[]::new);
}
In my program, the user enters a string, and it first finds the largest mode of characters in the string. Next, my program is supposed to remove all duplicates of a character in a string, (user input: aabc, program prints: abc) which I'm not entirely certain on how to do. I can get it to remove duplicates from some strings, but not all. For example, when the user puts "aabc" it will print "abc", but if the user puts "aabbhh", it will print "abbhh." Also, before I added the removeDup method to my program, it would only print the maxMode once, but after I added the removeDup method, it began to print the maxMode twice. How do I keep it from printing it twice?
Note: I cannot convert the strings to an array.
import java.util.Scanner;
public class JavaApplication3 {
static class MyStrings {
String s;
void setMyStrings(String str) {
s = str;
}
int getMode() {
int i;
int j;
int count = 0;
int maxMode = 0, maxCount = 1;
for (i = 0; i< s.length(); i++) {
maxCount = count;
count = 0;
for (j = s.length()-1; j >= 0; j--) {
if (s.charAt(j) == s.charAt(i))
count++;
if (count > maxCount){
maxCount = count;
maxMode = i;
}
}
}
System.out.println(s.charAt(maxMode)+" = largest mode");
return maxMode;
}
String removeDup() {
getMode();
int i;
int j;
String rdup = "";
for (i = 0; i< s.length(); i++) {
int count = 1;
for (j = 0; j < rdup.length(); j++) {
if (s.charAt(i) == s.charAt(j)){
count++;
}
}
if (count == 1){
rdup += s.charAt(i);
}
}
System.out.print(rdup);
System.out.println();
return rdup;
}
}
public static void main (String[] args) {
Scanner in = new Scanner(System.in);
MyStrings setS = new MyStrings();
String s;
System.out.print("Enter string:");
s = in.nextLine();
setS.setMyStrings(s);
setS.getMode();
setS.removeDup();
}
}
Try this method...should work fine!
String removeDup()
{
getMode();
int i;
int j;
String rdup = "";
for (i = 0; i< s.length(); i++) {
int count = 1;
for (j = i+1; j < s.length(); j++) {
if (s.charAt(i) == s.charAt(j)) {
count++;
}
}
if (count == 1){
rdup += s.charAt(i);
}
}
// System.out.print(rdup);
System.out.println();
return rdup;
}
Welcome to StackOverflow!
You're calling getMode() both outside and inside of removeDup(), which is why it's printing it twice.
In order to remove all duplicates, you'll have to call removeDup() over and over until all the duplicates are gone from your string. Right now you're only calling it once.
How might you do that? Think about how you're detecting duplicates, and use that as the end condition for a while loop or similar.
Happy coding!
Shouldn't this be an easier way? Also, i'm still learning.
import java.util.*;
public class First {
public static void main(String arg[])
{
Scanner sc= new Scanner(System.in);
StringBuilder s=new StringBuilder(sc.nextLine());
//String s=new String();
for(int i=0;i<s.length();i++){
String a=s.substring(i, i+1);
while(s.indexOf(a)!=s.lastIndexOf(a)){s.deleteCharAt(s.lastIndexOf(a));}
}
System.out.println(s.toString());
}
}
You can do this:
public static void main(String[] args) {
String str = new String("PINEAPPLE");
Set <Character> letters = new <Character>HashSet();
for (int i = 0; i < str.length(); i++) {
letters.add(str.charAt(i));
}
System.out.println(letters);
}
I think an optimized version which supports ASCII codes can be like this:
public static void main(String[] args) {
System.out.println(removeDups("*PqQpa abbBBaaAAzzK zUyz112235KKIIppP!!QpP^^*Www5W38".toCharArray()));
}
public static String removeDups(char []input){
long ocr1=0l,ocr2=0l,ocr3=0;
int index=0;
for(int i=0;i<input.length;i++){
int val=input[i]-(char)0;
long ocr=val<126?val<63?ocr1:ocr2:ocr3;
if((ocr& (1l<<val))==0){//not duplicate
input[index]=input[i];
index++;
}
if(val<63)
ocr1|=(1l<<val);
else if(val<126)
ocr2|=(1l<<val);
else
ocr3|=(1l<<val);
}
return new String(input,0,index);
}
please keep in mind that each of orc(s) represent a mapping of a range of ASCII characters and each java long variable can grow as big as (2^63) and since we have 128 characters in ASCII so we need three ocr(s) which basically maps the occurrences of the character to a long number.
ocr1: (char)0 to (char)62
ocr2: (char)63 to (char)125
ocr3: (char)126 to (char)128
Now if a duplicate was found the
(ocr& (1l<<val))
will be greater than zero and we skip that char and finally we can create a new string with the size of index which shows last non duplicate items index.
You can define more orc(s) and support other character-sets if you want.
Can use HashSet as well as normal for loops:
public class RemoveDupliBuffer
{
public static String checkDuplicateNoHash(String myStr)
{
if(myStr == null)
return null;
if(myStr.length() <= 1)
return myStr;
char[] myStrChar = myStr.toCharArray();
HashSet myHash = new HashSet(myStrChar.length);
myStr = "";
for(int i=0; i < myStrChar.length ; i++)
{
if(! myHash.add(myStrChar[i]))
{
}else{
myStr += myStrChar[i];
}
}
return myStr;
}
public static String checkDuplicateNo(String myStr)
{
// null check
if (myStr == null)
return null;
if (myStr.length() <= 1)
return myStr;
char[] myChar = myStr.toCharArray();
myStr = "";
int tail = 0;
int j = 0;
for (int i = 0; i < myChar.length; i++)
{
for (j = 0; j < tail; j++)
{
if (myChar[i] == myChar[j])
{
break;
}
}
if (j == tail)
{
myStr += myChar[i];
tail++;
}
}
return myStr;
}
public static void main(String[] args) {
String myStr = "This is your String";
myStr = checkDuplicateNo(myStr);
System.out.println(myStr);
}
Try this simple answer- works well for simple character string accepted as user input:
import java.util.Scanner;
public class string_duplicate_char {
String final_string = "";
public void inputString() {
//accept string input from user
Scanner user_input = new Scanner(System.in);
System.out.println("Enter a String to remove duplicate Characters : \t");
String input = user_input.next();
user_input.close();
//convert string to char array
char[] StringArray = input.toCharArray();
int StringArray_length = StringArray.length;
if (StringArray_length < 2) {
System.out.println("\nThe string with no duplicates is: "
+ StringArray[1] + "\n");
} else {
//iterate over all elements in the array
for (int i = 0; i < StringArray_length; i++) {
for (int j = i + 1; j < StringArray_length; j++) {
if (StringArray[i] == StringArray[j]) {
int temp = j;//set duplicate element index
//delete the duplicate element by copying the adjacent elements by one place
for (int k = temp; k < StringArray_length - 1; k++) {
StringArray[k] = StringArray[k + 1];
}
j++;
StringArray_length--;//reduce char array length
}
}
}
}
System.out.println("\nThe string with no duplicates is: \t");
//print the resultant string with no duplicates
for (int x = 0; x < StringArray_length; x++) {
String temp= new StringBuilder().append(StringArray[x]).toString();
final_string=final_string+temp;
}
System.out.println(final_string);
}
public static void main(String args[]) {
string_duplicate_char object = new string_duplicate_char();
object.inputString();
}
}
Another easy solution to clip the duplicate elements in a string using HashSet and ArrayList :
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Scanner;
public class sample_work {
public static void main(String args[]) {
String input = "";
System.out.println("Enter string to remove duplicates: \t");
Scanner in = new Scanner(System.in);
input = in.next();
in.close();
ArrayList<Character> String_array = new ArrayList<Character>();
for (char element : input.toCharArray()) {
String_array.add(element);
}
HashSet<Character> charset = new HashSet<Character>();
int array_len = String_array.size();
System.out.println("\nLength of array = " + array_len);
if (String_array != null && array_len > 0) {
Iterator<Character> itr = String_array.iterator();
while (itr.hasNext()) {
Character c = (Character) itr.next();
if (charset.add(c)) {
} else {
itr.remove();
array_len--;
}
}
}
System.out.println("\nThe new string with no duplicates: \t");
for (int i = 0; i < array_len; i++) {
System.out.println(String_array.get(i).toString());
}
}
}
your can use this simple code and understand how to remove duplicates values from string.I think this is the simplest way to understand this problem.
class RemoveDup
{
static int l;
public String dup(String str)
{
l=str.length();
System.out.println("length"+l);
char[] c=str.toCharArray();
for(int i=0;i<l;i++)
{
for(int j=0;j<l;j++)
{
if(i!=j)
{
if(c[i]==c[j])
{
l--;
for(int k=j;k<l;k++)
{
c[k]=c[k+1];
}
j--;
}
}
}
}
System.out.println("after concatination lenght:"+l);
StringBuilder sd=new StringBuilder();
for(int i=0;i<l;i++)
{
sd.append(c[i]);
}
str=sd.toString();
return str;
}
public static void main(String[] ar)
{
RemoveDup obj=new RemoveDup();
Scanner sc=new Scanner(System.in);
String st,t;
System.out.println("enter name:");
st=sc.nextLine();
sc.close();
t=obj.dup(st);
System.out.println(t);
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package javaapplication26;
import java.util.*;
/**
*
* #author THENNARASU
*/
public class JavaApplication26 {
public static void main(String[] args) {
int i,j,k=0,count=0,m;
char a[]=new char[10];
char b[]=new char[10];
Scanner ob=new Scanner(System.in);
String str;
str=ob.next();
a=str.toCharArray();
int c=str.length();
for(j=0;j<c;j++)
{
for(i=0;i<j;i++)
{
if(a[i]==a[j])
{
count=1;
}
}
if(count==0)
{
b[k++]=a[i];
}
count=0;
}
for(m=0;b[m]!='\0';m++)
{
System.out.println(b[m]);
}
}
}
i wrote this program. Am using 2 char arrays instead. You can define the number of duplicate chars you want to eliminate from the original string and also shows the number of occurances of each character in the string.
public String removeMultipleOcuranceOfChar(String string, int numberOfChars){
char[] word1 = string.toCharArray();
char[] word2 = string.toCharArray();
int count=0;
StringBuilder builderNoDups = new StringBuilder();
StringBuilder builderDups = new StringBuilder();
for(char x: word1){
for(char y : word2){
if (x==y){
count++;
}//end if
}//end inner loop
System.out.println(x + " occurance: " + count );
if (count ==numberOfChars){
builderNoDups.append(x);
}else{
builderDups.append(x);
}//end if else
count = 0;
}//end outer loop
return String.format("Number of identical chars to be in or out of input string: "
+ "%d\nOriginal word: %s\nWith only %d identical chars: %s\n"
+ "without %d identical chars: %s",
numberOfChars,string,numberOfChars, builderNoDups.toString(),numberOfChars,builderDups.toString());
}
Try this simple solution for REMOVING DUPLICATE CHARACTERS/LETTERS FROM GIVEN STRING
import java.util.Scanner;
public class RemoveDuplicateLetters {
public static void main(String[] args) {
Scanner scn=new Scanner(System.in);
System.out.println("enter a String:");
String s=scn.nextLine();
String ans="";
while(s.length()>0)
{
char ch = s.charAt(0);
ans+= ch;
s = s.replace(ch+"",""); //Replacing all occurrence of the current character by a spaces
}
System.out.println("after removing all duplicate letters:"+ans);
}
}
In Java 8 we can do that using
private void removeduplicatecharactersfromstring() {
String myString = "aabcd eeffff ghjkjkl";
StringBuilder builder = new StringBuilder();
Arrays.asList(myString.split(" "))
.forEach(s -> {
builder.append(Stream.of(s.split(""))
.distinct().collect(Collectors.joining()).concat(" "));
});
System.out.println(builder); // abcd ef ghjkl
}
This question already has an answer here:
Counting distinct words with Threads
(1 answer)
Closed 9 years ago.
I've asked this question before ( Counting distinct words with Threads ) and made the code more appropriate. As described in first question I need to count the distinct words from a file.
De-Bug shows that all my words are stored and sorted correctly, but the issue now is an infinite "while" loop in the Test class that keeps on going after reading all the words (De-bug really helped to figure out some points...).
I'm testing the code on a small file now with no more than 10 words.
DataSet class has been modified mostly.
I need some advice how to get out of the loop.
Test looks like this:
package test;
import java.io.File;
import java.io.IOException;
import junit.framework.Assert;
import junit.framework.TestCase;
import main.DataSet;
import main.WordReader;
public class Test extends TestCase
{
public void test2() throws IOException
{
File words = new File("resources" + File.separator + "test2.txt");
if (!words.exists())
{
System.out.println("File [" + words.getAbsolutePath()
+ "] does not exist");
Assert.fail();
}
WordReader wr = new WordReader(words);
DataSet ds = new DataSet();
String nextWord = wr.readNext();
// This is the loop
while (nextWord != "" && nextWord != null)
{
if (!ds.member(nextWord))
{
ds.insert(nextWord);
}
nextWord = wr.readNext();
}
wr.close();
System.out.println(ds.toString());
System.out.println(words.toString() + " contains " + ds.getLength()
+ " distinct words");
}
}
Here is my updated DataSet class, especially member() method, I'm still not sure about it because at some point I used to get a NullPointerExeption (don't know why...):
package main;
import sort.Sort;
public class DataSet
{
private String[] data;
private static final int DEFAULT_VALUE = 200;
private int nextIndex;
private Sort bubble;
public DataSet(int initialCapacity)
{
data = new String[initialCapacity];
nextIndex = 0;
bubble = new Sort();
}
public DataSet()
{
this(DEFAULT_VALUE);
nextIndex = 0;
bubble = new Sort();
}
public void insert(String value)
{
if (nextIndex < data.length)
{
data[nextIndex] = value;
nextIndex++;
bubble.bubble_sort(data, nextIndex);
}
else
{
expandCapacity();
insert(value);
}
}
public int getLength()
{
return nextIndex + 1;
}
public boolean member(String value)
{
for (int i = 0; i < data.length; i++)
{
if (data[i] != null && nextIndex != 10)
{
if (data[i].equals(value))
return true;
}
}
return false;
}
private void expandCapacity()
{
String[] larger = new String[data.length * 2];
for (int i = 0; i < data.length; i++)
{
data = larger;
}
}
}
WordReader class didn't change much. ArrayList was replaced with simple array, storing method also has been modified:
package main;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class WordReader
{
private File file;
private String[] words;
private int nextFreeIndex;
private BufferedReader in;
private int DEFAULT_SIZE = 200;
private String word;
public WordReader(File file) throws IOException
{
words = new String[DEFAULT_SIZE];
in = new BufferedReader(new FileReader(file));
nextFreeIndex = 0;
}
public void expand()
{
String[] newArray = new String[words.length * 2];
// System.arraycopy(words, 0, newArray, 0, words.length);
for (int i = 0; i < words.length; i++)
newArray[i] = words[i];
words = newArray;
}
public void read() throws IOException
{
}
public String readNext() throws IOException
{
char nextCharacter = (char) in.read();
while (in.ready())
{
while (isWhiteSpace(nextCharacter) || !isCharacter(nextCharacter))
{
// word = "";
nextCharacter = (char) in.read();
if (!in.ready())
{
break;
}
}
word = "";
while (isCharacter(nextCharacter))
{
word += nextCharacter;
nextCharacter = (char) in.read();
}
storeWord(word);
return word;
}
return word;
}
private void storeWord(String word)
{
if (nextFreeIndex < words.length)
{
words[nextFreeIndex] = word;
nextFreeIndex++;
}
else
{
expand();
storeWord(word);
}
}
private boolean isWhiteSpace(char next)
{
if ((next == ' ') || (next == '\t') || (next == '\n'))
{
return true;
}
return false;
}
private boolean isCharacter(char next)
{
if ((next >= 'a') && (next <= 'z'))
{
return true;
}
if ((next >= 'A') && (next <= 'Z'))
{
return true;
}
return false;
}
public boolean fileExists()
{
return file.exists();
}
public boolean fileReadable()
{
return file.canRead();
}
public Object wordsLength()
{
return words.length;
}
public void close() throws IOException
{
in.close();
}
public String[] getWords()
{
return words;
}
}
And Bubble Sort class for has been changed for strings:
package sort;
public class Sort
{
public void bubble_sort(String a[], int length)
{
for (int j = 0; j < length; j++)
{
for (int i = j + 1; i < length; i++)
{
if (a[i].compareTo(a[j]) < 0)
{
String t = a[j];
a[j] = a[i];
a[i] = t;
}
}
}
}
}
I suppose the method that actually blocks is the WordReader.readNext(). My suggestion there is that you use Scanner instead of BufferedReader, it is more suitable for parsing a file into words.
Your readNext() method could be redone as such (where scan is a Scanner):
public String readNext() {
if (scan.hasNext()) {
String word = scan.next();
if (!word.matches("[A-Za-z]+"))
word = "";
storeWord(word);
return word;
}
return null;
}
This will have the same functionality as your code (without using isCharacter() or isWhitespace() - the regex (inside matches())checks that a word contains only characters. The isWhitespace() functionality is built-in in next() method which separates words. The added functionality is that it returns null when there are no more words in the file.
You'll have to change your while-loop in Test class for this to work properly or you will get a NullPointerException - just switch the two conditions in the loop definition (always check for null before, or the first will give a NPE either way and the null-check is useless).
To make a Scanner, you can use a BufferedReader as a parameter or the File directly as well, as such:
Scanner scan = new Scanner(file);