Hey guys I'm trying to get the concept of recursion down by making a program that generates String of an ArrayList recursively. My basic algorithm is:
public static ArrayList<String> generateListOfAll1sStrings(int maxBits)
terminal condition: if maxBits is 1, return the simplest case: a list containing just "1"
otherwise:
recursively call generateListOfAll1sStrings() for the next-smallest bit-length, saving the list that is returned
find the longest string in that list and create a new string with "1" appended to it (making the next-longest string)
return a new list that contains all the elements of the shorter list along with the new string just added.
The code I have so far is:
package bincomb.model;
import java.util.ArrayList;
public class BinaryCombinationGenerator {
public static ArrayList<String> generateListOfAll1sStrings(int maxBits) {
String string = null;
ArrayList<String> listofJust1 = new ArrayList<String>();
ArrayList<String> otherArray = new ArrayList<String>();
int i = 1;
if (maxBits == 1) {
listofJust1.add("1");
return listofJust1;
}
if (maxBits > 1) {
for (String string2 : listofJust1) {
String comp = "";
if (!(comp.equals(string2))) {
comp = string2;
}
string = comp;
}
listofJust1.add(i, (string + "1"));
i++;
listofJust1 = BinaryCombinationGenerator.generateListOfAll1sStrings((maxBits-1));
System.out.println(listofJust1);
return listofJust1;
}
return listofJust1;
}
public static void main(String[] args) {
generateListOfAll1sStrings(10);
}
}
However, currently, I'm returning an IndexOutOfBoundsException. I think my for loop is causing the problem, but I'm not certain how to go about fixing it.
You're getting an java.lang.IndexOutOfBoundsException at this line listofJust1.add(i, (string + "1"));.
This is because the method list.add(index, objects) tries to add the object at index "1" but your array has 0 elements.
Either change it to listofJust1.add(i-1, (string + "1")); or simply listofJust1.add((string + "1"));
#Edit: here:
listofJust1.add(i, (string + "1"));
You want to add the string for the current (N) level of recursion but below you substitute this array with:
listofJust1 = BinaryCombinationGenerator.generateListOfAll1sStrings((maxBits-1));
Which basically says "get the result for (maxBits-1) and replace with it listofJust1" therefore you are losing what you added before.
Instead you should first get the list for level N-1 and then add the string for the current level:
listofJust1 = BinaryCombinationGenerator.generateListOfAll1sStrings((maxBits-1));
listofJust1.add(stringForThisLevel);
Also you need to rething how you are computing "string" at level N, doesn't seem right.
Related
I am trying to find the index of a value in a nested ArrayList, but I need to find the position of the first ArrayList. I am receiving an error when I run this code:
public int findCity(String city) {
city = "\"" + city + "\"";
System.out.println(cityArray.size());
for (List<String> value : cityArray) {
String newCity = value.get(1);
if (newCity == city) return cityArray.indexOf(value);
}
return -1;
}
The problem happens in the line after the for loop:
String newCity = value.get(1);
It's telling me that index 1 is out of bounds for length 1. Any help is greatly appreciated!
I found the problem: I was using nextLine() to read the csv file, and it was creating a new array every time there was a space. This was a huge oversight on my part, but now I can start fixing the problem.
Once again, sorry for the inconvinience.
You're mixing up cityArray.size() and cityArray.get(1).size(), which can be completely different.
(You are also comparing strings with ==, which is likely to cause disaster. Use .equals.)
i think the problem is that you start counting from 1, but an ArrayList starts counting from 0. This is why the index is out of bounds.
You could try this:
String newCity = value.get(0);
Below code can help you ,though I did not understand your problem.
public static void main(String[] args) {
List<String> list1 = Arrays.asList(new String[]{"A","B"});
List<String> list2 = Arrays.asList(new String[]{"Y","Z"});
List<List<String>> cityArray = new ArrayList<>(2);
cityArray.add(list1);
cityArray.add(list2);
System.out.println(findCity("Z", cityArray));
}
public static int findCity(String city, List<List<String>> cityArray) {
System.out.println(cityArray.size());
for (List<String> value : cityArray) {
for(String newCity :value) {
if (newCity.equalsIgnoreCase(city)) {
return cityArray.indexOf(value);
}
}
}
return -1;
}
I have a String arraylist called 'hand' that takes random elements from 3 different String arrays, PEOPLE, WEAPONS AND ROOMS. Is there any way I can determine if the arraylist has all but one element from each category? So if 'hand' contains 8 of the 9 Strings in the String array ROOMS, it will return the string that it doesn't have for that array? This method should only apply if 'hand' is missing EXACTLY 1 element from the specified array. If it's missing more than one element from a specified array, it shouldn't do anything.
import java.util.ArrayList;
import java.util.List;
public class Main {
public List<String> hand = new ArrayList<String>();
public final static String[] PEOPLE = new String[] {
"Miss. Scarlet",
"Mrs. Peacock",
"Colonel Mustard",
"Professor Plum",
"Mrs. White",
"Mr. Green"
};
public final static String[] WEAPONS = new String[] {
"Wrench",
"Candlestick",
"Pipe",
"Rope",
"Revolver",
"Knife"
};
public final static String[] ROOMS = new String[] {
"Library",
"Kitchen",
"Study",
"Conservatory",
"Ballroom",
"Lounge",
"Hall",
"Billiard Room",
"Dining Room"
};
public Main() {
hand.add("Library");
hand.add("Lounge");
hand.add("Wrench");
hand.add("Miss. Scarlet");
hand.add("Mrs. Peacock");
hand.add("Colonel Mustard");
hand.add("Professor Plum");
hand.add("Mrs. White");
}
public static void main(String[] args) {
Main main = new Main();
}
}
I guess this is what you're looking for: use removeAll() method on a List.
So, convert your arrays to List with Arrays.asList(..).
Than removeAll hands collection from each of your former arrays. If the size of the remaining List is 1 - this is what you are looking for.
List<String> peoples = new ArrayList<>(Arrays.asList(PEOPLE));
peoples.removeAll(hands);
if (peoples.size() == 1)
{
// here your hands List contained all items from PEOPLE, except 1
}
Declare a method that takes two parameters : the constant list and your hand and that will return a String : the missing String element in your hand if it is the last one missing or else null.
Call this method three times by passing at each time your hand and one of the three constant lists.
That's all.
In code it could give :
public String findLastMissingElement(String[] constants, List<String> hand){
String missingElement = null;
for (String constant : constants){
if (!hand.contains(constant) && missingElement==null){
missingElement = constant;
}
else if (!hand.contains(constant)){
return null;
}
}
return missingElement;
}
And you could call it in this way :
String missingPeople = findLastMissingElement(PEOPLE, hand);
String missingWeapon = findLastMissingElement(WEAPONS, hand);
String missingRoom = findLastMissingElement(ROOMS, hand);
So I have this homework (I am not trying to cheat) and I posed this question on our class forum, but I am having difficulty understanding the pseudocode that the professor wrote ... how it could possibly work.
The objective is to take a list of strings and "r","w","b" ...
then reorder them into 6 new strings ...
This is java I wrote based on his pseudocode:
public class Solution2 {
public static ArrayList<String> solve(ArrayList<String> base) {
ArrayList<String> temp = new ArrayList<String>();
ArrayList<String> result = new ArrayList<String>();
// Check for the empty set
if (base == null) {
ArrayList<String> empty = new ArrayList<String>();
return empty;
}
char first = 'y';
String firstString = "";
for (Iterator<String> i = base.iterator(); i.hasNext();) {
if (first == 'y') {
firstString = i.next();
base.remove(0);
first = 'n';
}
temp = solve(base);
for (Iterator<String> n = temp.iterator(); n.hasNext();) {
// Add first string
result.add(firstString + n.next());
}
return result;
//
}
return result;
}
}
I just don't know how you keep accumulating the main list of strings. I get an empty set ... which is the base case.
I think you should back up and consider a simpler case before you try to make sense of your professor's code, so you know what to look for.
Your recursive function needs a step where it returns a list with the new element added to it and also with the result of the next recursive call.
Say we have a function where we return a list made of the separate characters of a list:
static List<String> listChars(String s) {
if ("".equals(s)) return new ArrayList<String>();
List<String> ret = new ArrayList<>();
ret.add(s.substring(0,1));
ret.addAll(listChars(s.substring(1)));
return ret;
}
The test harness looks like
public static void main(String[] args) {
System.out.println("result of '' =" + listChars(""));
System.out.println("result of 'a'=" + listChars("a"));
System.out.println("result of 'abcd'=" + listChars("abcd"));
}
which prints
result of '' =[]
result of 'a'=[a]
result of 'abcd'=[a, b, c, d]
Your function doesn't have a case like this where you're adding the result of the current iteration plus the results from the next recursive call to the list that you're returning.
I am splitting my direcList into two sublists firstDirec and secondtDirec when a speciefic string New direction was found.
Then I am filtering particular strings out of the lists by not adding them to the new ArrayLists timeListFirst and timeListSecond. Everything works fine for the firstDirec, and the elements are not being added to the timeListFirst, but I am facing a problem with the secondtDirec list at this postion:
if (!(mergeLine.equals(otherDirection))
since here at this position mergeLine is equal to"Ravensbusch" and so is otherDirection. Despite this fact this string is being added to the timeListSecond. Can someone explain me my mistake?
mergeLine value:
otherDirection value:
for (String keyLine : direcList) {
if (keyLine.startsWith("New direction")) {
int index = direcList.indexOf(keyLine);
// direcArray.remove(index);
List<String> firstDirec = direcList.subList(0, index);
List<String> secondtDirec = direcList.subList(index,
direcList.size() - 1); // This part wih New
// Direction.
ArrayList<String> timeListFirst = new ArrayList<String>();
for (String mergeLine : firstDirec) {
if (!(mergeLine.equals(direction))
&& !(mergeLine.equals(route))
&& !(mergeLine.equals(day))) {
timeListFirst.add(mergeLine);
}
}
ArrayList<String> timeListSecond = new ArrayList<String>();
for (String mergeLine : secondtDirec) {
if (!(mergeLine.equals(otherDirection))
&& !(mergeLine.equals(route))
&& !(mergeLine.equals(day))
&& !(mergeLine.equals("New direction"))) {
timeListSecond.add(mergeLine);
}
}
It looks like otherDirection's value has a space at the end of it, therefore they are not equal and since there's a ! in there, the entire expression is true.
I have a List of Strings, and most of them are multiple words:
"how are you"
"what time is it"
I want to remove the space from every string in this list:
"howareyou"
"whattimeisit"
I know of the Collections.replaceAll(list, to replace, replace with), but that only applies to Strings that are that exact value, not every instance in every String.
What you must is to apply the replace function to each of the string in your list.
And as the strings are immutable you will have to create another list where string with no space will be stored.
List<String> result = new ArrayList<>();
for (String s : source) {
result.add(s.replaceAll("\\s+", ""));
}
Immutable means that object can not be changed, it must be created new one if you want to change the state of it.
String s = "how are you";
s = s.replaceAll("\\s+", "");
The function replaceAll returns the new string if you did not assign it to variable s then would still have spaces.
It doesn't sound very useful.
But try this:
import java.util.Arrays;
import java.util.List;
/**
* http://stackoverflow.com/questions/20760578/how-do-i-replace-characters-in-every-string-in-my-list-in-java/20760659#20760659
* Date: 12/24/13
* Time: 7:08 AM
*/
public class SpaceEater {
public static void main(String[] args) {
List<String> stringList = Arrays.asList(args);
System.out.println("before: " + stringList);
for (int i = 0; i < stringList.size(); ++i) {
stringList.set(i, stringList.get(i).replaceAll("\\s+", ""));
}
System.out.println("after : " + stringList);
}
}
disrvptor was correct - original snippet did not alter the list. This one does.
You can try this:
No need to define new array list. Use list.set this set replaces the element at the specified position in this list with the specified element.
int i = 0;
for (String str : list)
{
list.set(i, str.replaceAll(" ", ""));
i++;
}
Output
for (String s : list)
{
System.out.println(s);
}
//Thisisastring
//Thisisanotherstring
The only way I know how to do this is to iterate over the list, perform the replace operation on every object and replace the original object with the new one. This is best handled with 2 lists (source and target).