trouble with arrays and array lists - java

This is for class homework. She is making us use array and array list in two parts. Basically she is showing us how using arraylist is alot easier than arrays.
I am having alot of trouble getting the array part to work.
Create a class called CustomerLister1 with a main method that instantiates an array of String objects called customerName. The array should have room for six String objects. Use an initializer list to put the following names into the array:
Chris
Lois
Meg
Peter
Stewie
Write an enhanced for loop to display the array of names. What is displayed for the last array element? Why is it that value?
Add the Strings "Meg" and "Brian" into index 3, and 4, respectively, so that the array contains the following elements:
Chris
Lois
Meg
Meg
Brian
Peter
Stewie
Write an enhanced for loop to display the array of names.
Write a second, traditional for loop that checks each element for the String “Meg”, if found in the array, remove it, shift the remaining elements, and display the array of names. Are both instances of "Meg" removed correctly from the array?
This is my code
public class CustomerLister1
{
public static void main(String[] args)
{
String[] customerName = new String[7];
customerName[0] = "Chris";
customerName[1] = "Lois";
customerName[2] = "Meg";
customerName[3] = "Peter";
customerName[4] = "Stewie";
for (int i = customerName.length-1;i > 3; i--)
{
customerName[i] = customerName[i - 2];
}
customerName[3] = "Meg";
customerName[4] = "Brian";
for (int m = 0; m <= customerName.length-1; m++)
{
if(customerName[m].equals("Meg"))
{
for(int j = m;j < customerName.length;j++)
{
if(j < customerName.length-2) {
customerName[j]= customerName[j+1];
} else {
customerName[j]="";
}
}
m--;
}
for (String element : customerName)
{
System.out.println(element);
}
}
}
}
The output is wrong though it removes both the megs and then adds brian peter then two empty lines and then stewie. I need the empty lines to be gone and the output to print continuously.

Here's a solution. It uses an aditional counter to know when you should put the "" in the array instead of shifting the next element.
int customerSize = 7;
for (int m = 0; m <= customerName.length-1; m++)
{
if(customerName[m].equals("Meg"))
{
customerSize--;
for(int j = m;j < customerName.length;j++)
{
if(j >= customerSize)
customerName[j] = "";
else
customerName[j] = customerName[j+1];
}
m--;
for (String element : customerName)
{
if(! element.equals(""))
System.out.println(element);
}
System.out.println();
}
}
Output:
Chris
Lois
Meg
Brian
Peter
Stewie
Chris
Lois
Brian
Peter
Stewie

Related

ArrayList throwing "java.lang.ArrayIndexOutOfBoundsException"

I know from reading other questions on the forumn that Array indexing is causing the problem, but I don't know any way around it. I commented where the throw happens. The whole throw is
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 35
at assignment4.AnagramUtil.getLargestAnagramGroup(AnagramUtil.java:82)
at assignment4.AnagramTester.main(AnagramTester.java:36)
If anyone has any ideas how I can make this work, let me know. Also, I don't think any more of my methods are relevant in solving this but I can put them here if needed.
/*areAnagrams
* parameters: sorted strings x & y
* returns boolean
* implements sort method
*/
public static boolean areAnagrams(String x, String y)
{
if(sort(x).equals(sort(y)))
return true;
return false;
}
/*
* This function takes a string array and finds the largest anagram group.
* AnagramComparator.insertionSort() sorts the array by placing anagrams together,
* so no sorting is needed.
* I use ArrayList because I want to be able to freely add to the string array.
* returns a new String[]
*/
public static String[] getLargestAnagramGroup(String[] input)
{
String[] s=input;
AnagramComparator.insertionSort(s, new AnagramComparator());
int largestCount = 0, tempCount=1;
ArrayList<String> largest= new ArrayList<String>();
ArrayList<String> temp= new ArrayList<String>();
for(int i=0; i<s.length; i++)
{
//since it's already sorted, we need only to compare.
//add
temp.add(s[i]);
//Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 35
if (areAnagrams(s[i],s[i+1])) //at assignment4.AnagramUtil.getLargestAnagramGroup(AnagramUtil.java:82)
{
//add s[i+1] to array list
temp.add(s[i+1]);
tempCount++;
}
else
{
//if tempcount> largestcount, empty contents of largest and make temp largest
if (tempCount>largestCount)
{
if(!largest.isEmpty())
largest.clear();
largest=temp;
largestCount=tempCount;
}
//reset tempcount
tempCount=1;
}
}
String[] result= new String[largest.size()];
for (int j=0;j<largest.size();j++)
result[j]=largest.get(j);
return result;
}
your problem is here:
areAnagrams(s[i],s[i+1])
this will fail when i = s.length - 1 because of i + 1 (when i = s.length it is out of bounds, as length returns the number of elements, yet array index starts at 0)
change
for(int i=0; i<s.length; i++)
to
for(int i=0; i<s.length - 1; i++)
Try changing this line:
for(int i=0; i<s.length; i++)
to this:
for(int i=0; i<s.length-1; i++)
You have a loop
for(int i=0; i<s.length; i++) {...
which means that for the maximum allowable value of i, s[i] will be the last element in s.
But within the loop you are referencing s[i + 1], which is past the end of s.

Permutation of an ArrayList [duplicate]

This question already has answers here:
Permutation algorithm for array of integers in Java
(9 answers)
Closed 8 years ago.
There's a lot of guide on finding Permutation for a String, but how would I do this for every element in an ArrayList? Given that:
ArrayList<String> list = [bob, cat, dog]
Output:
[bob, cat, dog]
[bob, dog, cat]
[dog, bob, cat]
[dog, cab, bob]
....
Here's a code that I have that will permute a single word:
public class permutations {
public ArrayList<String> performPermutations(String s){
ArrayList<String> arrayList = new ArrayList<String>();
if (s == null) {
return null;
}
else if (s.length() == 0) {
arrayList.add("");
return arrayList;
}
else {
for (int i = 0; i < s.length(); i++) {
ArrayList<String> remaining = performPermutations(s.substring(0, i) + s.substring(i + 1));
for (int j = 0; j < remaining.size(); j++) {
arrayList.add(s.charAt(i) + remaining.get(j));
}
}
return arrayList;
}
}
public static void main(String[] args) {
permutations p = new permutations();
ArrayList<String> arr = p.performPermutations("abc");
for(int i = 0; i<arr.size();i++) {
System.out.println(arr.get(i));
}
}
See the code here for permutation of numbers :
Java code for permutation of a list of numbers
And now in your case, the list of numbers will be nothing but the list of indices for the ArrayList of strings. So basically permutation of indices will lead to permutation of the strings.
A simple solution to reverse anything (words in a sentence, items in a list etc) is to use a stack:
create a stack
loop on each item of your list, push the current item on the stack
loop on each item of the stack, pop the current item in a new list
That may not be the best in terms of performance though, but it works with everything as long as you can put it in a stack. And the two loops are not embedded in each other, so it's better than your example.

Arrays and Array lists

I have most of my program done, but it's not working as I need it to and I've stared at it for a while and I just can't figure it out. Can someone help me notice what I am doing wrong? I'm not asking for someone to just fix it, but explain it.
Create a class called CustomerLister1 with a main method that instantiates an array of String objects called customerName. The
array should have room for seven String objects. Assign each of the
following Strings to sequential locations in the array beginning at
array index 0.
Chris
Lois
Meg
Peter
Stewie
Write an enhanced for loop to display the array of names. What is displayed for the last two array elements? Why is it that value?
Add the Strings “Meg” and “Brian” into index 3, and 4, respectively, so that the array contains the following elements:
Chris
Lois
Meg
Meg
Brian
Peter
Stewie
Write an enhanced for loop to display the array of names.
Write a second, traditional for loop that checks each element for the String “Meg”, if found in the array, remove it, shift the
remaining elements, and display the array of names. Are both
instances of “Meg” removed correctly from the array?
Modify the code you wrote part #1 for a second class called CustomerLister2 so that you are using an ArrayList instead of an array
to store the names as String objects.
Add the five names as done previously, and then add “Brian” so that it
is the 4th name in the ArrayList. Now add “Meg” into the third
position in the list (there will be two identical strings “Meg” in the
list).
Use an enhanced for loop for displaying all the String objects, as in
part #1 and use a traditional for loop to remove “Meg” and show the
revised ArrayList. Once again, was “Meg” removed completely from the
list?
public class CustomerLister1
{
public static void main(String[] args)
{
String[] customerName = new String[7];
customerName[0] = "Chris";
customerName[1] = "Lois";
customerName[2] = "Meg";
customerName[3] = "Peter";
customerName[4] = "Stewie";
for (int i = customerName.length-1; i > 3; i--)
{
customerName[i] = customerName[i - 2];
}
customerName[3] = "Meg";
customerName[4] = "Brian";
for (int m = 0; m <= customerName.length-1; m++)
{
if (customerName[m].equals("Meg"))
{
for (int j = m; j < customerName.length; j++)
{
if (j < customerName.length-2)
{
customerName[j] = customerName[j+1];
} else {
customerName[j] = "";
}
}
m++;
}
for (String element : customerName)
{
System.out.println(element);
}
}
}
}
First, an "enhanced" loop (I think) is a for-each loop. It looks like this in java.
for (String name : customerName) {
System.out.println(name);
}
whereas a traditional for loop is iteration, which is what you were doing.
for (int i = 0; i < num; i++) {
System.out.println(customerName[i]);
}
You are printing too much output mainly because your last for loop is embedded too far. Let me increase the tab stops to make it more obvious.
for (int m = 0; m <= customerName.length-1; m++)
{
if (customerName[m].equals("Meg"))
{
for (int j = m; j < customerName.length; j++)
{
if (j < customerName.length-2)
{
customerName[j] = customerName[j+1];
} else {
customerName[j] = "";
}
}
m++;
}
for (String element : customerName)
{
System.out.println(element);
}
}
Do you see how your last for loop is embedded into your first one? This means everytime the first for loop for (int m = 0; m <= customerName.length-1; m++) runs, the last for loop is ALSO going to run. Which means the entire loop runs m times.
For a mathematical explanation, LoopA runs n times. LoopB runs m times. If LoopB is inside of LoopA then LoopB will run a total of n * m times.
The problem with many outputs is obvious as you have your printing loop inside your "enhanced" loop, whatever that means.
Other than that you should use <= in your innermost loop as you also want to move the very last element.

ArrayList.remove is not working in a loop

I have following code-
import java.util.ArrayList;
public class ArrayListExp{
public static void main (String[] args){
ArrayList<String> name = new ArrayList<String>();
name.add("Chris");
name.add("Lois");
name.add("Meg");
name.add("Meg");
name.add("Brain");
name.add("Peter");
name.add("Stewie");
System.out.println(name);
for ( int i = 0; i < name.size(); i++){
String oldName = name.get(i);
if(oldName.equals("Meg"))
{
name.remove(i);
}
}
System.out.println(name);
}
}
But here it gives me output -
[Chris, Lois, Meg, Meg, Brain, Peter, Stewie]
[Chris, Lois, Meg, Brain, Peter, Stewie]
I am not getting the point, why this is not removing Meg but I have tried with only one Meg in that case it is working. And I when I am adding few more Meg in last the one Meg is not removed from the ArrayList. Why?
When you remove the first "Meg", the index i=2. Then it's incremented, but since one of the "Meg" is already removed, now name.get(3) is "Brain". So you didn't actually check the second "Meg".
To fix the problem. you can decrement the index when you remove an element:
public class ArrayListExp{
public static void main (String[] args){
ArrayList<String> name = new ArrayList<String>();
name.add("Chris");
name.add("Lois");
name.add("Meg");
name.add("Meg");
name.add("Brain");
name.add("Peter");
name.add("Stewie");
System.out.println(name);
for ( int i = 0; i < name.size(); i++){
String oldName = name.get(i);
if(oldName.equals("Meg"))
{
name.remove(i);
i--;
}
}
System.out.println(name);
}
}
You are iterating over the first Meg, and when that Meg gets removed, the array values shift over by one.
[Chris, Lois, Meg, Meg, Brain, Peter, Stewie]
0 1 2 3 4 5 6
First Meg gets removed, and the loop increments i because it finished executing everything inside the for loop, so i will now be 3 and the array has been modified:
[Chris, Lois, Meg, Brain, Peter, Stewie]
0 1 2 3 4 5
Try iterating backwards.
for ( int i = name.size() - 1; i >= 0; i--){
String oldName = name.get(i);
if(oldName.equals("Meg"))
{
name.remove(i);
}
}
You can use name.removeAll(Arrays.asList("Meg")); to remove all "Meg"
Your complete code would be
for ( int i = 0; i < name.size(); i++){
String oldName = name.get(i);
if(oldName.equals("Meg"))
{
name.removeAll(Arrays.asList("Meg"));
}
}
You're removing from the ArrayList while iterating over it from 0 to N, so when you remove the first Meg at index N, the next Meg moves down to index N, then you increment i to N+1. So the 2nd Meg doesn't get removed. Try iterating in the opposite order (N to 0):
for ( int i = name.size() - 1; i >= 0; i--) {
Its because when i=2 and if condition is true then meg is deleted and all the indices are shifted up. hence the next i will point to Brain, not meg.
try this. (decrease i by one when if condition holds true)
for ( int i = 0; i < name.size(); i++){
String oldName = name.get(i);
if(oldName.equals("Meg"))
{
name.remove(i);
i--;
}
}
While removing elements you should not use for loop. It always make problems when implementing some logic. Use reverse for loop for your problem and always try to use for each.
Java 8+
The Collection interface now provides a removeIf method that modifies it in place, to which you provide a predicate that returns true if the element should be removed.
You can thus use a lambda like so:
name.removeIf(name -> name.equals("Meg"));
A method reference can be used as well to be more concise. The following code will also work if there are null elements.
name.removeIf("Meg"::equals);
If you do not want to modify the old list, you can use Stream and filter to get a List of all the items that should be retained by negating the condition.
final List<String> filtered = name.stream()
.filter(name -> !"Meg".equals(name))
.collect(Collectors.toList());
If you specifically need an ArrayList, use Collectors.toCollection with a constructor reference instead.
final ArrayList<String> filtered = name.stream()
.filter(name -> !"Meg".equals(name))
.collect(Collectors.toCollection(ArrayList::new));
Pre Java 8
The issue is that the ArrayList is being modified while being iterated over, which changes its size and shifts later elements forward; this is a problem if there are consecutive elements that need to be removed. You need to decrease the index by one each time you remove an element since that index will now refer to the next element.
for (int i = 0; i < name.size(); i++) {
String oldName = name.get(i);
if (oldName.equals("Meg")) {
name.remove(i);
i--;//Important!
}
}
Looping backwards will also fix this problem, as elements will never be shifted to a position that have yet to be checked.
for (int i = name.size() - 1; i >= 0; i--) {
String oldName = name.get(i);
if (oldName.equals("Meg")) {
name.remove(i);
}
}
Generally, using an Iterator is the most appropriate for this sort of operation, as it supports removing elements while iterating through calling Iterator#remove. This also modifies the List in place. For more complex operations, consider using a ListIterator.
final Iterator<String> it = name.iterator();
while(it.hasNext()){
final String name = it.next();
if(name.equals("Meg")){
it.remove();
}
}

Java function needed for finding the longest duplicated substring in a string?

Need java function to find the longest duplicate substring in a string
For instance, if the input is “banana”,output should be "ana" and we have count the number of times it has appeared in this case it is 2.
The solution is as below
public class Test{
public static void main(String[] args){
System.out.println(findLongestSubstring("i like ike"));
System.out.println(findLongestSubstring("madam i'm adam"));
System.out.println(findLongestSubstring("When life hands you lemonade, make lemons"));
System.out.println(findLongestSubstring("banana"));
}
public static String findLongestSubstring(String value) {
String[] strings = new String[value.length()];
String longestSub = "";
//strip off a character, add new string to array
for(int i = 0; i < value.length(); i++){
strings[i] = new String(value.substring(i));
}
//debug/visualization
//before sort
for(int i = 0; i < strings.length; i++){
System.out.println(strings[i]);
}
Arrays.sort(strings);
System.out.println();
//debug/visualization
//after sort
for(int i = 0; i < strings.length; i++){
System.out.println(strings[i]);
}
Vector<String> possibles = new Vector<String>();
String temp = "";
int curLength = 0, longestSoFar = 0;
/*
* now that the array is sorted compare the letters
* of the current index to those above, continue until
* you no longer have a match, check length and add
* it to the vector of possibilities
*/
for(int i = 1; i < strings.length; i++){
for(int j = 0; j < strings[i-1].length(); j++){
if (strings[i-1].charAt(j) != strings[i].charAt(j)){
break;
}
else{
temp += strings[i-1].charAt(j);
curLength++;
}
}
//this could alleviate the need for a vector
//since only the first and subsequent longest
//would be added; vector kept for simplicity
if (curLength >= longestSoFar){
longestSoFar = curLength;
possibles.add(temp);
}
temp = "";
curLength = 0;
}
System.out.println("Longest string length from possibles: " + longestSoFar);
//iterate through the vector to find the longest one
int max = 0;
for(int i = 0; i < possibles.size();i++){
//debug/visualization
System.out.println(possibles.elementAt(i));
if (possibles.elementAt(i).length() > max){
max = possibles.elementAt(i).length();
longestSub = possibles.elementAt(i);
}
}
System.out.println();
//concerned with whitespace up until this point
// "lemon" not " lemon" for example
return longestSub.trim();
}
}
This is a common CS problem with a dynamic programming solution.
Edit (for lijie):
You are technically correct -- this is not the exact same problem. However this does not make the link above irrelevant and the same approach (w.r.t. dynamic programming in particular) can be used if both strings provided are the same -- only one modification needs to be made: don't consider the case along the diagonal. Or, as others have pointed out (e.g. LaGrandMere), use a suffix tree (also found in the above link).
Edit (for Deepak):
A Java implementation of the Longest Common Substring (using dynamic programming) can be found here. Note that you will need to modify it to ignore "the diagonal" (look at the Wikipedia diagram) or the longest common string will be itself!
In Java : Suffix Tree.
Thanks to the ones that have found how to solve it, I didn't know.

Categories

Resources