Android randomize strings without repetition - java

I'm doing a simple random quiz app in Android. So basically I have string array of words. I need to display the string without repetition. This is what I've tried so far:
String[] words = { "Welcome", "Different", "Teenager", "Transfer", "Italian",
"Timber", "Toxic", "Illiterate", "Irate", "Moderate", "Transportation", "Attention" };
ArrayList<String> wordlist = new ArrayList<String>();
for (String i : words)
wordlist.add(i);
Collections.shuffle(wordlist);
randomStr = words[new Random().nextInt(words.length)];
tvWord.setText("");
tvWord.setText(randomStr);
But I still get the random word repeating. What am I doing wrong in here? Any ideas? I would gladly appreciate your help. Thanks.
Update:
First on a button click the word should then display. And many times I click the button I keep getting the same word again.
switch(v.getId()){
case R.id.btPlay:
randomWordList();
break;
}
Where randomWordList(); is the method I posted above.

You don't keep track of what was already used. I also don't understand why you define wordlist and then don't use it. Just a small modification of your code will do the trick.
Edit: You also need to initialize values in different scope than where you use it. For example like this:
public class MyClass{
LinkedList<String> wordlist;
public MyClass(){
String[] words = { "Welcome", "Different", "Teenager", "Transfer", "Italian",
"Timber", "Toxic", "Illiterate", "Irate", "Moderate", "Transportation", "Attention" };
wordlist = new LinkedList<String>();
for (String i : words)
wordlist.add(i);
Collections.shuffle(wordlist);
}
public void useNextWord(){
tvWord.setText("");
tvWord.setText(wordlist.pollLast());
}

Create a new list of Strings and shuffle it. Then simply iterate over the shuffled list from the beginning.
ArrayList<String> copyOfWords= new ArrayList<String>(words);
Collections.shuffle(copyOfWords);
This is taken from here.
Time complexity is O(n).
To iterate over the List you can either get the first element and remove it (with the same method) or keep track which was the last used element.
First solution:
String randomWord = copyOfWords.remove(0);
tvWord.setText(randomWord);
P.S. do not use this line in your code randomStr = words[new Random().nextInt(words.length)];

You will need to either keep track of the Strings you have already used in another array or list and check the value has not already been used or alternatively remove any used Strings from the pool. You can do that with String next = List.remove(index).

You first shuffle your list with Collections.shuffle(wordlist); and then access the list with a random index. There's no need to use a random index if the list is already shuffled. Just get one item after another. You could use wordlist.remove(0) until your list is empty.
Display the next string as follows:
if (!wordlist.isEmpty()) {
randomStr = wordlist.remove(0);
tvWord.setText(randomStr);
}

Related

How to find the number of unique words in array list

So I am trying to create an for loop to find unique elements in a ArrayList.
I already have a ArrayList stored with user input of 20 places (repeats are allowed) but I am stuck on how to count the number of different places inputted in the list excluding duplicates. (i would like to avoid using hash)
Input:
[park, park, sea, beach, town]
Output:
[Number of unique places = 4]
Heres a rough example of the code I'm trying to make:
public static void main(String[] args) {
ArrayList<City> place = new ArrayList();
Scanner sc = new Scanner(System.in);
for(...) { // this is just to receive 20 inputs from users using the scanner
...
}
# This is where i am lost on creating a for loop...
}
you can use a Set for that.
https://docs.oracle.com/javase/7/docs/api/java/util/Set.html
Store the list data to the Set.Set will not have duplicates in it, so the size of set will be the elements without duplicates.
use this method to get the set size.
https://docs.oracle.com/javase/7/docs/api/java/util/Set.html#size()
Sample Code.
List<String> citiesWithDuplicates =
Arrays.asList(new String[] {"park", "park", "sea", "beach", "town"});
Set<String> cities = new HashSet<>(citiesWithDuplicates);
System.out.println("Number of unique places = " + cities.size());
If you are able to use Java 8, you can use the distinct method of Java streams:
int numOfUniquePlaces = list.stream().distinct().count();
Otherwise, using a set is the easiest solution. Since you don't want to use "hash", use a TreeSet (although HashSet is in most cases the better solution). If that is not an option either, you'll have to manually check for each element whether it's a duplicate or not.
One way that comes to mind (without using Set or hashvalues) is to make a second list.
ArrayList<City> places = new ArrayList<>();
//Fill array
ArrayList<String> uniquePlaces = new ArrayList<>();
for (City city : places){
if (!uniquePlaces.contains(city.getPlace())){
uniquePlaces.add(city.getPlace());
}
}
//number of unique places:
int uniqueCount = uniquePlaces.size();
Note that this is not super efficient =D
If you do not want to use implementations of Set or Map interfaces (that would solve you problem with one line of code) and you want to stuck with ArrayList, I suggest use something like Collections.sort() method. It will sort you elements. Then iterate through the sorted array and compare and count duplicates. This trick can make solving your iteration problem easier.
Anyway, I strongly recommend using one of the implementations of Set interface.
Use following answer. This will add last duplicate element in distinct list if there are multiple duplicate elements.
List<String> citiesWithDuplicates = Arrays.asList(new String[] {
"park", "park", "sea", "beach", "town", "park", "beach" });
List<String> distinctCities = new ArrayList<String>();
int currentIndex = 0;
for (String city : citiesWithDuplicates) {
int index = citiesWithDuplicates.lastIndexOf(city);
if (index == currentIndex) {
distinctCities.add(city);
}
currentIndex++;
}
System.out.println("[ Number of unique places = "
+ distinctCities.size() + "]");
Well if you do not want to use any HashSets or similar options, a quick and dirty nested for-loop like this for example does the trick (it is just slow as hell if you have a lot of items (20 would be just fine)):
int differentCount=0;
for(City city1 : place){
boolean same=false;
for(City city2 : place){
if(city1.equals(city2)){
same=true;
break;
}
}
if(!same)
differentCount++;
}
System.out.printf("Number of unique places = %d\n",differentCount);

is there anyway in java to see if a variable matches a list of words?

is there any way in java that i can check a list of words to see if a variable matches any of them, and if it does I want to increment a counter. I know I create a lot of if statements but I think a list of some sort would make the program easier to navigate.
For example if variable 1 is equal to any in the list increment positive value.
String vbl1 = "happy";
then i would have a few lists like:
list 1:
joyful
great
excited
happy
thanks in advance guys.
Use java.util.List or any other datastructure that implements java.util.Collection. As suggested in comments, java.util.Set may suit better if ordering does not matter.
You can check if a given items exists in the list by using contains() method.
List<String> list = new ArrayList<>();
list.add("joyful");
list.add("great");
list.add("excited");
list.add("happy");
boolean contains = list.contains("happy");
Ignoring case you can do
list.contains(yourWord)
This will return true if there is a match so you can increment your counter then.
If you want to consider case I think the clearest way will be to loop through the list and calling equals on each item in the list
Edit: as per comment in another answer a set may be cleaner and more efficient as it will remove any duplicates you have in your list (although won't guarantee an order
)
Yes, perhaps with something like this
public static void main(String[] args) {
String[] words = { "joyful", "great", "excited",
"happy" };
java.util.List<String> list1 = java.util.Arrays
.asList(words);
String vbl1 = "happy";
if (list1.contains(vbl1)) {
System.out.printf("%s contains %s\n",
java.util.Arrays.toString(words), vbl1);
} else {
System.out.printf("%s does not contain %s\n",
java.util.Arrays.toString(words), vbl1);
}
}
Which outputs
[joyful, great, excited, happy] contains happy
String[] words = { "joyful", "great", "excited","happy" };
String matchStr = "happy";
for(String i:words){
if(i.equals(matchStr)){
// Increment Counter Here
}
}

I have a bunch of words (strings?) in an ArrayList and I'd like to know if I can find the size of each element?

So like the title says: I have a bunch of words in an ArrayList and I want to know how I can get the size of each element in the ArrayList. For example:
ArrayList input = new Arraylist();
input = {"Hello", "Goodbye", "Segall", "Ty"};
Id like to know if there is a way to find out the length of the first element which, in this case, would be "Hello". I had something in mind like:
input(0).size();
That obviously doesn't work.
I also tried setting up variable for it like this:
String variable = input.get(0);
variable.length() or variable.size();
But turns out-- input is an object and variable is expecting a string type.
I am a beginner to this so if this stupidly easy question I apologize!
Either typecast your object coming from the list like this(String)input.get(0);
or make your array list declaration like this
ArrayList<String> input = new ArrayList<String>(); // Preferred way.
So that you don't need a cast.
And finally you can call variable.length() to get the length.
For one thing, you don't specify that it is an array list of String. When declaring the array list, you want to use
ArrayList<String> input = new ArrayList<String>();
Then for each element you want to add, use
input.add("myString");
Check this-
final List<String> input = new ArrayList<String>() {
{
add("Hello");
add("Goodbye");
add("Segall");
add("Ty");
}
};
for(String word : input) {
System.out.println(word + " --> " + word.length());
}

How do I make an ArrayList of ArrayLists from an ArrayList by using a function that makes ArrayLists in an ArrayList from Strings of an ArrayList [duplicate]

This question already has answers here:
Looping in ArrayLists with a Method
(3 answers)
Closed 9 years ago.
I have a java program that
reads a text file,
puts all it's words in an ArrayList
puts all the words into an ArrayList, lowercase with punctuation removed
I now want to make two more things.
A function that creates all the anagrams of the strings of a String ArrayList,
an ArrayList of ArrayLists that will store each of the anagrams and the original string into each ArrayList in the ArrayList.
So I want to develop a function that will take a string that I am inserting from one ArrayList into a new ArrayList and make all it's anagrams and put them in an ArrayList and then put that ArrayList in the ArrayList that is reading the old ArrayList.
Something that will look like this:
List<String> arLists = new ArrayList<String>(); //makes new array list
for(String arList : words) //takes values from old array list
ArrayList<String> anaLists = new ArrayList<String>(); //makes a new array list
arLists.add(anag(anaLists,arList,"")); //uses a function that makes an
I want to make a function kinda like this, but what I have made here... doesn't really work.
public void anag(ArrayList<String> anaLists, String s1, String s2){
if(s1.length() == 0){
return anaLists;
}
for(int i = 0 ; i < s1.length() ; i++){ //only runs for string length
String anaList = anag(s1.substring(0, i) + s1.substring(i+1, s1.length()), s1.charAt(i) + s2);
anaLists.add(anaList);
}
}
Some guidance on this would be superb.
To make all anagrams from a string, follow the following steps:
Step 1: Use String's replace to remove whitespace, and make sure all punctuation and capitalization has been removed.
Step 2: Write this function f(string s, string anagram, ArrayList<String> array) and call it with s = yourstring, anagram = "", array = new ArrayList<String>():
If s is empty, add anagram to array and return
For each letter l in s:
newanagram = anagram + l
news = s with l taken out of it (e.g. make a substring of everything before l in s and everything after l in s, and concatenate them together)
call f(news, anagram, array)
This will explore a 'tree' of recursive self calls, and at each 'leaf' of the 'tree' each possible permutation of all the letters will be added to the array. When it finishes, n*n-1*n-2*n-3... aka n factorial entries will be in the array, which is how you know you're on the right track :)
And if you need an anagram of every string in an arraylist, just call it in a for loop.
After some struggle, I have tried to understand your question and here's my answer. Correct me if I am wrong. First of all, you can do all that pre-processing stuff like changing case, removing grammar using one array list. Now to the actual function:
public void getAnag(String baseStr, ArrayList<String> finalAnagList)
{
ArrayList<String> anagList = new ArrayList<String>();
anagList = getAnagrams(baseStr); // getAnagrams is a support function to get the anagrams
anagList.add(baseStr); // I suppose you want to add the base string also to the anagrams list
finalAnagList.add(anagList);
}
And your calling function in program would be:
public void testAnagrams()
{
ArrayList<String> words = getWordsFromFile("/home/list.txt"); // gets the words from the file
ArrayList<String> anagramsList = new ArrayList<String>();
foreach(String word : words)
{
getAnag(word, anagramsList);
}
}

How to find total number of different items within an arraylist.

I've done some searching but I wasn't able to find a valid solution. I have an arraylist storing Strings such as gum, socks, OJ, dog food...
I am having trouble iterating the list to determine the total number of differnt types of items.
ie.
ArrayList<String> Store = new ArrayList<String>();
this.Store.add("Gum");
this.Store.add("Gum");
this.Store.add("Socks");
this.Store.add("Candy");
The list has 4 total items, but only three different kinds of items (Gum, Sucks, Candy).
How would I design a method to calculate the 3?
What Bhesh Gurung said, but in code:
int numUnique = new HashSet<String>(Store).size();
If what you actually have is StoreItems and need to go through getName() then I would do
Set<String> itemNames = new HashSet<String>();
for (StoreItem item : Store)
itemNames.add(item.getName());
int numUnique = itemNames.size();
Use a Set (HashSet) whose size will give you what you are looking for.
This looks like a homework... So, if you do not understand the HashSet solution proposed above (or doning the same with a HashMap), think about doing something like this:
Create a new ArrayList
Take an element and check to see if it exists in the new ArrayList
If it is present in the new ArrayList, do nothing. Else add it.
Do this until you have examined the last element of the ArrayList.
Then, the size of the new array list should be the number you are looking for.
You can use the lastIndexOf method and loop through the arraylist.
char count=0;
for(char i=0; i<araylist.size(); i++){
if(i == araylist.lastIndexOf(araylist.get(i))){
count++;
}
}
Tested.

Categories