I'm having trouble reversing a LinkedList. In other words, I need them sorted in z-a order (in contrast to a-z). I've tried Collections.reverse but is not coming into effect? I have the following:
import java.io.*;
import java.util.*;
public class pa9Driver {
//create two list
//1st List is of type word class
//2nd list is of type Anagram_Family
public static List<Word> words = new LinkedList<Word>();
public static List<AnagramFamily> familyList = new LinkedList<AnagramFamily>();
//a main method for driver class
public static void main(String[] args) {
//call the generate method to read word from the file
generate_WordList();
//sort the word list
Collections.sort(words);
//generate the anagram family for the word
generate_FamilyList();
//sort the anagram family list
Collections.sort(familyList, new anagramFamilyComparator());
//reverse the anagram family list
Collections.reverse(familyList);
topFive();
}//main ends
public static void topFive() {
int i;
for(i = 0; i < 15; i++) {
System.out.print(familyList.get(i).getCanonicalForm1() + ", ");
System.out.print(familyList.get(i).getSize() + ": ");
System.out.println(familyList.get(i));
}
}
//method that read word
public static void generate_WordList() {
File inFile12=new File("words.txt");
Scanner fileRead1=null;
try {
fileRead1 = new Scanner(inFile12);
} catch (Exception exe) {
exe.printStackTrace();
System.exit(0);
}
//until the file has words read the words
while(fileRead1.hasNext()) {
words.add(new Word(fileRead1.next()));
}
}
//generate the anagram and add it to the current family
public static void generate_FamilyList() {
Iterator<Word> readWord1 = words.iterator();
Word previousWord1 = words.get(0);
familyList.add(new AnagramFamily());
int index1 = 0;
while(readWord1.hasNext()) {
Word currentWord1 = readWord1.next();
if(currentWord1.getCanonicalForm1().equals(previousWord1
.getCanonicalForm1())) {
familyList.get(index1).add(currentWord1);
} else {
index1++;
familyList.add(new AnagramFamily());
familyList.get(index1).add(currentWord1);
}
previousWord1 = currentWord1;
}
}
}
For convenience sake, I'll only show the first few lines of code that I have and that is expected.
Currently:
[apers, apres, asper, pares, parse, pears, prase, presa, rapes, reaps, spare, spear]
[alerts, alters, artels, estral, laster, ratels, salter, slater, staler, stelar, talers]
Expected:
[spear, spare, reaps, rapes, presa, prase, pears, parse, pares, asper, apres, apers]
[talers, stelar, staler, slater, salter, ratels, laster, estral, artels, alters, alerts]
Try:
Collections.sort(familyList, Comparator.reverseOrder());
Alternatively, you can do:
Collections.sort(familyList, new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
return o2.compareTo(o1);
}
});
//Print list in reverse order
for(String st : familyList){
System.out.println(st);
}
Seeing your code, it seems AnagramFamily is a kind of List, which you are not sorting.
You need to sort the AnagramFamily (List of String) with a StringComparator for getting your desired output.
I think you can use compareTo for this action no ? compareTo from Comparable
Related
I have started learning the Dynamic Programming, in that way I have written a program to find and written longest common substring of two given strings and it is executing fine, after that I went on to google and search for the same, but everyone is using matrix or (double dimension array) to store the subproblem solutions. But I have used only single dimension and I believe, time complexity of my solution is O(n*m). I just want to confirm that my solution is really dynamic programming or not.
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.ArrayList;
public class LongestCommonSubstring {
private class LCSUtility {
int lengthOfLCS;
ArrayList<String> lcsList;
LCSUtility() {
lcsList = new ArrayList<>();
lengthOfLCS=0;
}
}
public LCSUtility findLongestCommonSubstring(String str1,String str2) {
int[] lcs = new int[str1.length()];
LCSUtility lcsUtility= new LCSUtility();
/* Filling out the 1-D array with 1 if that character from "first string is existed in "second string" otherwise 0"*/
for(int i=0;i<str1.length();i++){
if(str2.contains(str1.substring(i,i))) {
lcs[i] =1;
} else {
lcs[i] =0;
}
}
/* Finding the sub strings of "first string" are part of "second string" and storing results into 1-D array*/
for(int i=1;i<str1.length();i++){
String sub = str1.substring(i-1,i+1);
if(str2.contains(sub)) {
lcs[i] = 1+lcs[i-1];
}
}
/* Finding Max of the LCSs*/
for(int i=0;i<lcs.length;i++){
System.out.print(" " + lcs[i]);
if(lcs[i]>lcsUtility.lengthOfLCS) {
lcsUtility.lengthOfLCS=lcs[i];
}
}
/* Adding out all lcs to the utility object's list*/
for(int i=0;i<lcs.length;i++) {
if(lcs[i] == lcsUtility.lengthOfLCS) {
lcsUtility.lcsList.add(str1.substring(i-lcsUtility.lengthOfLCS+1,i+1));
}
}
return lcsUtility;
}
public static void main(String[] args){
LCSUtility lcsUtility = new LongestCommonSubstring().findLongestCommonSubstring("tutorialhorizon", "dynamictutorialProgramming hellow");
System.out.print(" ******* Longest Common Sub of Given Strings are \n");
for(String s: lcsUtility.lcsList) {
System.out.print(" " +s);
}
}
}
I have the following code, and I have sort the array list alphabetically in the main method, as the user inputs his strings.
Here is my code:
import java.util.Scanner;
import java.util.ArrayList;
class Main{
public static void main(String[] args) {
ArrayList<String> names = new ArrayList<String>();
Scanner scan = new Scanner(System.in);
String name;
do{
System.out.println("Enter the next name: ");
name = scan.nextLine();
String toUpperCase = titleCase(name);
if(!toUpperCase.equals("Stop")){
names.add(toUpperCase);
}
} while(!name.equalsIgnoreCase("STOP"));
System.out.println(names.toString());
}
public static String titleCase(String s){
String output = s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
return output;
}
}
Please don't give any generic answers, I've been struggling with this for a while now. If the answer seems simple to you, it probably isn't for me.
replace this line:
names.add(toUpperCase);
with this:
int index = names.size();
for (int i = 0; i < names.size(); i++) {
if (names.get(i).compareTo(toUpperCase) > 0) {
index = i;
break;
}
}
names.add(index, toUpperCase);
so, every time you have new string from user - you will insert it into proper position of your array list
this method is quite slow, but ok for home assignment
As suggested in the comments, the most simple way of maintaining a sorted data structure upon each insert is to use a TreeSet or any other data structure that maintains sorted order internally. Instead of declaring an ArrayList<String> you would simply need to modify your code to this:
Set<String> names = new TreeSet<>();
Scanner scan = new Scanner(System.in);
String name;
do {
System.out.println("Enter the next name: ");
name = scan.nextLine();
String toUpperCase = titleCase(name);
if(!toUpperCase.equals("Stop")){
names.add(toUpperCase);
}
} while(!name.equalsIgnoreCase("STOP"));
From Javadocs for TreeSet:
the Set interface is defined in terms of the equals operation, but a TreeSet instance performs all element comparisons using its compareTo (or compare) method, so two elements that are deemed equal by this method are, from the standpoint of the set, equal. The behavior of a set is well-defined even if its ordering is inconsistent with equals; it just fails to obey the general contract of the Set interface.
Please try below code. You can replace the sorting algorithm with more efficient algorithm like merge sort/selection sort etc..
import java.util.Scanner;
import java.util.ArrayList;
class alsort{
public static void main(String[] args) {
ArrayList<String> names = new ArrayList<String>();
Scanner scan = new Scanner(System.in);
String name;
do{
System.out.println("Enter the next name: ");
name = scan.nextLine();
String toUpperCase = titleCase(name);
if(!toUpperCase.equals("Stop")){
names.add(toUpperCase);
}
} while(!name.equalsIgnoreCase("STOP"));
System.out.println(names.toString());
for(int i=0;i<name.length();i++){
for(int j=i;j<=name.length();j++){
if(names.get(i).compareTo(names.get(j))>0){
String tmp=names.get(i);
names.set(i, names.get(j));
names.set(j, tmp);
}
}
}
System.out.println(names.toString());
}
public static String titleCase(String s){
String output = s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
return output;
}
}
public class SortedArrayList<T> extends ArrayList<T> {
/**
*
*/
private static final long serialVersionUID = 1L;
#SuppressWarnings("unchecked")
public void insertSorted(T value) {
add(value);
Comparable<T> cmp = (Comparable<T>) value;
for (int i = size()-1; i > 0 && cmp.compareTo(get(i-1)) < 0; i--)
Collections.swap(this, i, i-1);
}
public static void main(String[] s){
SortedArrayList<String> myList = new SortedArrayList<String>();
myList.insertSorted("ddd");
myList.insertSorted("aaa");
myList.insertSorted("xyz");
System.out.println(myList);
}
}
this is what I have so far
public class RandomCharacter
{
public static char getRandomUpperCaseLetter()
{
int ascii = (int) (Math.random()*26) + (int) 'A';
return (char)ascii;
}
public static char getRandomDigitCharacter()
{
int digit = (int)(Math.random()*10) + (int) '0';
return (char)digit;
}
public static void main(String [] args)
{
for (int i = 1; i <= 100; i++)
{
System.out.print(getRandomUpperCaseLetter());
if(i%10 == 0)
System.out.print("\n");
}
}
}
I have no clue how to specifically order this alphabetically, I have tried for hours but could not find anything for this. Would someone be able to use my code to teach me how this works?
To sort the values, you must first store them in some data structure eg.an array list before sorting them. Then , if you have used a sortable collection such as the array list, you can use the .sort() method and the list will be sorted automatically.
eg/ref:
http://beginnersbook.com/2013/12/how-to-sort-arraylist-in-java/
For natural ordering you can just add the generated alphabets in string and call Collections.sort(listVariable) . This should answer your question.
Sample program
import java.util.*;
public class Details {
public static void main(String args[]){
ArrayList<String> listofcountries = new ArrayList<String>();
listofcountries.add("India");
listofcountries.add("US");
listofcountries.add("China");
listofcountries.add("Denmark");
/*Unsorted List*/
System.out.println("Before Sorting:");
for(String counter: listofcountries){
System.out.println(counter);
}
/* Sort statement*/
Collections.sort(listofcountries);
/* Sorted List*/
System.out.println("After Sorting:");
for(String counter: listofcountries){
System.out.println(counter);
}
}
}
I've written a java picnic game (very basic), the only thing I don't know how to do is get the program not to accept items of the same letter. I also want the program to list how many times the user entered a rejected item. Note that this allows any ordering of items, as long as no two items start with the same letter (dis-
regarding case). An acceptable sequence of inputs would be
mustard
,
ketchup
,
tofu
,
anchovies
.
However,
mustard
,
ketchup
,
tofu
, and
Kettle corn
would not work since \
Kettle corn
" begins
with the same letter as \
ketchup
" (ignoring case).
import java.util.*;
public class PlayPicnic
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
Picnic picnic = new Picnic();
ArrayList<String> unaccepted = new ArrayList<>();`enter code here`
while (picnic.numberOfItems() < 5)
{
System.out.print("What do you want to bring on the picnic? ");
String item = scan.nextLine();
if (picnic.okayToBring(item))
{
picnic.add(item);
}
else
{
if(!unaccepted.contains(item)) unaccepted.add(item);
System.out.println("Sorry, you can't bring " + item);
}
}
System.out.println("\nHere's what we'll have at the picnic:");
picnic.show();
System.out.println(Arrays.toString(unaccepted.toArray()));
}
}
corresponding class
import java.util.*;
public class Picnic
{
// INSTANCE VARIABLES:
private ArrayList<String> stuffToBring; // items to bring on the picnic
// CONSTRUCTOR:
//-----------------------------------------------------
// Construct a new Picnic.
//-----------------------------------------------------
public Picnic()
{
stuffToBring = new ArrayList<String>(); // initialize list
}
//-----------------------------------------------------
// Given an item s, see if it's okay to add it to the list.
// Return true if it is, false otherwise:
//-----------------------------------------------------
public boolean okayToBring(String s)
{
// "Secret rule" -- s can't be an item already in the list:
if (stuffToBring.contains(s)) // "contains" is in the ArrayList class
{
return false;
}
else
{
return true;
}
}
//-----------------------------------------------------
// Given an item s, add it to the list (if it's okay to add it)
//-----------------------------------------------------
public void add(String s)
{
if (okayToBring(s)) // this test keeps people from cheating!
{
stuffToBring.add(s);
}
}
//-----------------------------------------------------
// Print the items in the list
//-----------------------------------------------------
public void show()
{
for (int i = 0; i < stuffToBring.size(); i++)
{
String s = stuffToBring.get(i);
System.out.println(s);
}
}
//-----------------------------------------------------
// Returns the number of items in the list:
//-----------------------------------------------------
public int numberOfItems()
{
return stuffToBring.size();
}
}
Make a custom Set to remove duplicate, if first char is same(ignoring the case).
Set<String> unaccepted =new TreeSet<>(new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
Character first=Character.toLowerCase(o1.charAt(0));
Character second=Character.toLowerCase(o2.charAt(0));
return first.compareTo(second);
}
});
Now, add the value to this Set. It will ignore the same first Character data.
Change the while loop like below,
while (unaccepted.size()<5){
System.out.print("What do you want to bring on the picnic? ");
String item = scan.nextLine();
unaccepted.add(item);
}
Here is logic for checking for items in list with first char
public boolean checkItem(String input, List<String> items) {
String inputFirstChar = input.substring(0, 1);
boolean exist = false;
for (String item : items) {
String itemFirstChar = item.substring(0, 1);
if(itemFirstChar.equalsIgnoreCase(inputFirstChar)) {
exist = true;
break;
}
}
return exist;
}
private ArrayList<String> stuffToBring;
make your reference variable type with interface not the ArrayList implementation, do like this one
private List<String> stuffToBring;
To reject words with a used first letter, you put a simple String in class "Picnic":
private String usedLetters = "";
Then in method "okayToBring" you check if the letter is already used:
public boolean okayToBring(String s) {
return (usedLetters.indexOf(s.toLowerCase().charAt(0)) == -1); // letter not contained in String
}
and in method "add" you append the new word's first character to this String:
public void add(String s)
{
if (okayToBring(s))
{
stuffToBring.add(s);
usedLetters += s.toLowerCase().charAt(0);
}
}
Regarding your second question, your phrasing is a bit unclear. If you want to count how many times a specific item has been unsuccessfully entered, you could use a Hashmap to store rejected Strings and their count:
private HashMap<String, int> unaccepted = new HashMap<String, int>();
Then your program's "else" clause looks like follows:
int newcount = (unaccepted.containsKey(item) ? unaccepted.get(item)++ : 1);
unaccepted.put(item, newcount);
System.out.println("Sorry, you can't bring " + item + "(" + unaccepted.get(item) + " unsuccessful tries)");
If you just want to count the total number of unsuccessful entries, use a Set and println(unaccepted.size());
I am confused with the GenericQueue. With only add elements (queue.enqueue) and remove elements (queue.dequque) from it, how can I display a reverse words from user input?
To be more specific, I have the following code for java.
import java.util.Scanner;
public class displayreverse {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
GenericQueue<String> queue = new GenericQueue<String>();
System.out.print("Enter some words: ");
String words = input.nextLine();
queue.enqueue(words);
System.out.println(queue);
}
}
The output will look like this:
run:
Enter some words: who are you
Queue; [who are you]
How will I use the GenericQueue in order for it to display it in reverse order? The output should be like: "you are who" instead of "who are you"
My GenericQueue class is as follows:
public class GenericQueue<E> {
private java.util.LinkedList<E> list = new java.util.LinkedList<E>();
public void enqueue(E e){
list.addLast(e);
}
public E dequeue(){
return list.removeFirst();
}
public int getSize(){
return list.size();
}
public String toString(){
return "Queue; " + list.toString();
}
}
Thanks...
Create enqueueFirst method in GenericQueue as add the elements in front(or change enqueue to add in front not last)
public void enqueueFirst(E e){
list.addFirst(e);
}
For receiving the words all in same line using enqueueFirst as below:
System.out.print("Enter some words: ");
String wordsLine = input.nextLine();
String[] words = wordsLine.split(" ");//split the words separated by space
for(String word: words){
queue.enqueueFirst(word);//add one word at a time
}
Rest looks fine.