Duplicate Checker in Java - java

Ok, I'm new to this site but I do know that I'm not supposed to ask HW questions on here, but what I am asking is indeed HW BUT it has already been finished and submitted (and graded), I'm just here to hopefully get my program running with a better understanding:)
To prove that I've already completed it and not trying to pull a fast one, here's a link to the submission page:
http://i959.photobucket.com/albums/ae76/GoWxGaiA/HWDone_zps8ae79bf7.png
Now on the program...I'm supposed to be creating a program that checks for duplicate strings from the user input, and then output all the 'unique' strings in sorted order (ones that were not duplicates), and then output the 'non-unique' ones in sorted order right underneath the prior output. My instructor told us that we had to use a 'Triple nested loop' which I assume is just a for loop inside a for loop inside a for loop...I get all the up to the point where I need to store the strings in an array in which case I cannot and have not found another way around. What I submitted for this assignment is this:
package Homework2;
import java.util.Scanner;
public class Homework2 {
public static void main(String[] args) {
Scanner stdin = new Scanner(System.in);
System.out.println("Enter a list of words:");
String[] words = stdin.nextLine().split(" ");
System.out.println(words.length);
String[] array = new String[words.length];
for (int i = 0; i < words.length; i++) {
if(words == words)
for (int j = 0; j < words.length; j++) {
array[j] = words;
System.out.println(array[j]);
}
}
}
}
Again, I want to stress that I've already submitted this assignment and am just looking to properly complete this assignment to further my understanding.
Any help would be greatly appreciated!

A rather simple solution that I like to use for this problem:
Set<String> used = new HashSet<>();
public boolean wasUsed(String s) {
return used.add(s);
}
//using the method
if (wasUsed(yourString)) {
// duplicate!
}
Sets contain only 1 of an element, and will return false when adding a duplicate. Makes things really easy for management.
As for your scenario, I would simply keep a separate Set of words, and remove them when you hit a duplicate.
You can read up more on Java's Collections To learn about these helpful tools.

There are two obvious compile-time problems with this code:
words == words is always true. I guess you are trying to test wether there is a duplicate with this line, but this is not the way to do this.
array[j] = words tries to assign a String[] to a String variable.
This assignment is actually a little bit harder than it would seem at first glance. The trickiest part is printing the unique string in sorted order. The most practical solution is to use a linked list for this, which allows easy insertion in the middle of the list. I did assume that the use of Collections.sort() was not allowed. I guess it's possible that the use of LinkedList is also not allowed, but you didn't mention that in your question.
String[] words = { "1", "4", "2", "4", "3", "1" };
LinkedList<String> unique = new LinkedList<String>();
LinkedList<String> duplicates = new LinkedList<String>();
unique.add(words[0]);
for (int i = 1; i < words.length; i++)
{
boolean found = false;
for (String uniqueWord : unique)
{
if (words[i].equals(uniqueWord))
{
duplicates.add(words[i]);
found = true;
break;
}
}
if (!found)
{
boolean added = false;
for (int index = 0; index < unique.size(); index++)
{
if (words[i].compareTo(unique.get(index)) < 0)
{
unique.add(index, words[i]);
added = true;
break;
}
}
if (!added)
unique.addLast(words[i]);
}
}
for (String word : unique)
System.out.println(word);
System.out.println("--");
for (String word : duplicates)
System.out.println(word);

Related

Remove elements from ArrayList after finding element with specific char

I have an ArrayList that contains a number of Strings, I want to be able to iterate through the ArrayLists contents searching for a string containing a semicolon. When the semicolon is found I then want to delete all of the Strings including and after the semicolon string.
So;
this, is, an, arra;ylist, string
Would become:
this, is, an
I feel like this is a very simple thing to do but for some reason (probably tiredness) I can't figure out how to do it.
Here's my code so far
public String[] removeComments(String[] lineComponents)
{
ArrayList<String> list = new ArrayList<String>(Arrays.asList(lineComponents));
int index = 0;
int listLength = list.size();
for(String str : list)
{
if(str.contains(";"))
{
}
index++;
}
return lineComponents;
}
This becomes trivial with Java 9:
public String[] removeComments(String[] lineComponents) {
return Arrays.stream(lineComponents)
.takeWhile(s -> !s.contains(";"))
.toArray(String[]::new);
}
We simply form a Stream<String> from your String[] lineComponents and take elements until we find a semicolon. It automatically excludes the element with the semicolon and everything after it. Finally, we collect it to a String[].
First of all I think you are confusing arrays and arraylists. String[] is an array of strings while ArrayList<String> is an arraylist of strings. Take into account that those are not the same and you should read Array and ArrayList documentation if needed.
Then, to solve your problem following the ArrayList approach you can go as follows. Probably it's not the optimum way to do it but it will work.
public List<String> removeComments(List<String> lineComponents, CharSequence finding)
{
ArrayList<String> aux = new ArrayList<String>();
for(String str : lineComponents)
{
if(str.contains(finding))
break;
else
aux.add(str);
}
return aux;
}
This example is just for performance and bringing back my old favorite arraycopy:
public String[] removeComments(String[] lineComponents) {
int index = -1;
for (int i = 0; i < lineComponents.length; i++) {
if ( lineComponents[i].contains(";") ) {
index = i;
break;
}
}
if (index == -1) return lineComponents;
return Arrays.copyOf(lineComponents, index);
}

Putting Strings in Lexicographic Order

This is my assignment, and I am not sure how to proceed. The output only prints my first four teachers, and I don't know why it isn't printing my last three teachers as well. Thanks!
Create an ArrayList called teachers. Fill the ArrayList with your teacher’s LAST NAMES ONLY in the order that you see them during the day (Period 1: Jensen, Period 2: Houge, Period 3: …, etc.) You only need to put the teacher’s last name in the ArrayList, so it would print [Jensen, Houge, etc…].) Print the ArrayList using a print method.
Write a method that takes your teachers ArrayList, and from it makes a new ArrayList called ordered, whererin your teacher’s names are now in lexicographic order. Print the resulting ArrayList. (DO NOT CHANGE YOUR ORIGINAL ARRAYLIST, MAKE A NEW ONE!)
import java.util.ArrayList;
public class LexicographicOrdering
{
public static void main (String [] args){
ArrayList<String> teachers = new ArrayList<String>();
teachers.add("Turnbow");
teachers.add("Dyvig");
teachers.add("Williams");
teachers.add("Houge");
teachers.add("Allaire");
teachers.add("Violette");
teachers.add("Dorgan");
System.out.println(teachers);
order(teachers);
}
public static void order(ArrayList<String> teachers ){
ArrayList<String> ordered = new ArrayList<String>();
for(int i = 0; i < teachers.size(); i++){
String str = teachers.get(i);
for(int j = 1; j < teachers.size(); j++){
if(str.compareTo(teachers.get(j)) > 0){
str = teachers.get(j);
}
}
ordered.add(str);
teachers.remove(str);
}
System.out.print(ordered);
}
}
So the issue here is with your static order method. As Karl suggests above, you want to break the method into two separate parts. The first will create an ArrayList named 'ordered' and then fill it with the data contained in the 'teachers' array.
ArrayList<String> ordered = new ArrayList(); //the second <String> is not required
for(int i = 0; i < teachers.size(); i++){
String str = teachers.get(i);
ordered.add(str);
}
The next objective is to sort the array in alphabetical order, which can be achieved using the Collections.sort(ArrayList) method which is contained in the java.util package.
Collections.sort(ordered);
And now you need to print the ArrayList.
System.out.println(ordered);
As this is a homework assignment, I would recommend reading up on the Collections.sort() method, along with an example of it. A quick google search pulled up the following website: http://beginnersbook.com/2013/12/how-to-sort-arraylist-in-java/
Also, I would recommend reading the API for the Collection class. https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#sort-java.util.List-
Edit:
At a quick glance, I would assume the reason that your string is cutting out the last 3 names is due to the fact that you are removing items from the list as you are looking at each position in the list. Essentially, you are looking at every other item in the list because of this.
So I figured it out! I only needed to set the first for loop back to zero. Here is the new code:
import java.util.ArrayList;
public class LexicographicOrdering
{
public static void main (String [] args){
ArrayList<String> teachers = new ArrayList<String>();
teachers.add("Turnbow");
teachers.add("Dyvig");
teachers.add("Williams");
teachers.add("Houge");
teachers.add("Allaire");
teachers.add("Violette");
teachers.add("Dorgan");
System.out.println(teachers);
order(teachers);
}
public static void order(ArrayList<String> teachers ){
ArrayList<String> ordered = new ArrayList<String>();
for(int i = 0; i < teachers.size(); i++){
String str = teachers.get(i);
for(int j = 1; j < teachers.size(); j++){
if(str.compareTo(teachers.get(j)) > 0){
str = teachers.get(j);
}
}
i =- 1;
ordered.add(str);
teachers.remove(str);
}
System.out.print(ordered);
}
}

How to remove a word from a linked list that has a vowel as the first character in Java

This is the first time I am having to use a linkedlist. I understand how to iterate through it properly, and how to set one up. The problem I am having is I am unsure how to properly do this in combing it with checking if the first letter of a word is a vowel, and if so removing that word from the list. Here is my code so far:
import java.util.*;
public class LinkedListExample
{
public static void main(String args[])
{
//Linked List Declaration
LinkedList<String> linkedlist = new LinkedList<String>();
Scanner sc=new Scanner(System.in);
for(int i = 0; i<4; i++)//filling the list
{
System.out.println("What is your word?");
String yourValue = sc.next();
linkedlist.add(yourValue);
sc.nextLine();
}
Iterator<String> i = linkedlist.iterator();
while (i.hasNext())
{
String vowels = "aeiouy";
//Need to remove the words with the vowels as the first letter here
}
while(i.hasNext())//printing out new list
{
System.out.println(i.next());
}
}
}
I know I must use a for loop to make this work. My first thought was using a for loop to check against my string vowels, but I was unsure how to make that work with a linked list. I am also unsure how to remove something here while using an iterator to iterate through the linked list.
List<String> filteredList = list.stream().filter(n->n.startsWith("a")||n.startsWith("e")||n.startsWith("i")||n.startsWith("o")||n.startsWith("u")).collect(Collectors.toList());
List<String> unique = new ArrayList<String>(list);
unique.removeAll(filteredList);
unique.forEach(System.out::println);
here made an array list that contains words that starts with a,e,i,o,u and then I had created an array list that contain all elements then i removed elements that are present in filtered list unique list is your required list. I hope my post would be helpful cheers.
while (i.hasNext())
{
String vowels = "aeiouy";
//Need to remove the words with the vowels as the first letter here
boolean found = false;
String str = i.next();
for(int counter = 0; counter < vowels.length(); counter++)
if(vowels.charAt(counter) == str.charAt(0)) {
found = true;
break;
}
if(found) { /* do stuff here */}
}
EDIT:
After that, and before printing the new values, you have to reinitialize the iterator again by doing: i = linkedlist.iterator();. Pay attention to that. :)

get value that occurs more than one in a list?

What are the the best methods to get values that occur more than once in a large list of words without slowing my run time?. My file contains 1xx,xxx words and I put them into a linked list. Now, I want to get only the words that occur more than once out of that list.
For example, if a list contains:
....This is is is just a test test....
I want to get is and test and put them into another list using an iterator.
I don't know if my code is right, and I think that this is not the best solution to approach for this problem.
for(int i = 0; i < word.size(); i++) {
Word s = word.get(i);
Word s1 = word.get(i+1);
if(s.equals(s1)) {
newWord.add(s);
}
}
Put them all into HashSet instead of list and check the return value of add() method.
HashSet<Word> wordSet = new HashSet<>();
for(int i = 0; i < word.size(); i++) {
if(!wordSet.add(word.get(i)){
//Found duplicate
}
}
Note that you can also do it during/instead of creation of the list of the words.
Build a hashmap with the word as key and it count as value.
for(each word in list)
{
count = 1;
if(map.contains(word))
{
count = map.get(word);
}
else
count = 1;
map.put(word,count);
}
Then iterate over the hashmap and check if values is 1, and add the word to your list.
If you can sort the list, then finding duplicates is quick and easy.

I want to get a specific combination of permutation?

I want to get specific combination of permutation of string like alphabet. To understand me, I'll show you the code that I using:
public class PermutationExample {
public static List<String> getPermutation(String input) {
List<String> collection = null;
if (input.length() == 1) {
collection = new ArrayList<String>();
collection.add(input);
return collection;
} else {
collection = getPermutation(input.substring(1));
Character first = input.charAt(0);
List<String> result = new ArrayList<String>();
for (String str : collection) {
for (int i = 0; i < str.length(); i++) {
String item = str.substring(0, i) + first
+ str.substring(i);
result.add(item);
}
String item = str.concat(first.toString());
result.add(item);
}
return result;
}
}
public static void main(String[] args) {
System.out.println(PermutationExample.getPermutation("ABCD"));
}
}
This code works well and i can get every combination, I can take it from the list, if I need 5-th element, I can receive it. But if the string is the alphabet ... , didn't works, it's too big. What I have to do, to get the specific element like 1221-th from all 26! combinations ?
I solved a similar problem a while ago, only in python.
If what you need is simply the n-th permutation, then you can do a lot better then generating every permutation and returning the n-th, if you try to think about generating only the permutation you need.
You can do this "simply" by figuring out what should be the element in front for the number of permutations you want, and then what should be the remaining of the elements recursively.
Assume a collection of values [0, ... ,X], for any values such that col[n] < col[n+1]
For N elements, there are N! possible permutations, the case when the collection will be perfectly reversed.
We will see the change in the head of the collection after each (N-1)! permutations, so if n < (N-1)!, the head is the head. You then have a remaining number of permutations, and you can apply the same logic recursively.
Does this help? I know it's fairly high level and you'll have to think a bit about it, but maybe it'll get you on the right track.

Categories