Arrays and Array lists - java

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.

Related

How to sort number when entering vector in java

I want to add numbers in sorted way before entering vector. But the result is not right and I am confused where the problem is ? Output is shown below.
I want to sort using some algorithm without any inbuilt methods.
import java.util.Vector;
public class Test {
public static void main(String ar[]){
//Numbers to enter in vector
int[] number = {5,2,98,3,10,1};
Vector<Integer> v = new Vector<Integer>();
v.add(number[0]);
for(int i=1;i<number.length;i++){
for(int j=v.size();j>0;j--){
System.out.println("Entered: "+number[i]);
if(number[i] <= v.get(j-1)){
v.add(j-1,number[i]);
break;
}else{
v.add(j,number[i]);
break;
}
}
}
for(int s:v)
System.out.print(s + " ");
}
}
OUTPUT:
Entered: 2
Entered: 98
Entered: 3
Entered: 10
Entered: 1
2 5 3 10 1 98
You have a second (inner) for loop based on the variable j, but that "loop" will only execute exactly one time. Both conditions inside the j loop cause the loop to exit (break;).
When you're adding each number, the only possibilities are last or next to last.
Your inner for loop doesn't actually loop.
Regardless of the condition number[i] <= v.get(j-1),
the loop will exit after one step.
What you want to do is,
iterate from the beginning of the vector,
and when you find an element that's bigger than the one you want to insert,
then insert it, and break out of the loop.
This is opposite of what you did so far, which is iterating from the end of the vector.
If the end of the loop is reached without inserting anything,
then append the value.
The program badly needs some other improvements too:
If you don't need the vector to be thread-safe, then you don't need Vector. Use ArrayList instead.
The special treatment for the first number is unnecessary.
The outer loop can be written in a more natural way using the for-each idiom.
No need to loop to print the elements, the toString implementation of Vector is already easy to read.
The variable names are very poor and can be easily improved.
The indentation is inconsistent, making the code very hard to read.
With the problem fixed and the suggestions applied:
List<Integer> list = new ArrayList<>();
for (int current : numbers) {
boolean inserted = false;
for (int j = 0; j < list.size(); j++) {
if (current <= list.get(j)) {
list.add(j, current);
inserted = true;
break;
}
}
if (!inserted) {
list.add(current);
}
}
System.out.println(list);
Last but not least, instead of searching for the insertion point by iterating over the list,
you could achieve much better performance using binary search,
especially for larger sets of values.
Another simple solution would be:
import java.util.Vector;
public class Test {
public static void main(String ar[]){
//Numbers to enter in vector
int[] number = {5,2,98,3,10,1};
Vector<Integer> v = new Vector<Integer>();
v.add(number[0]);
for(int i=1, j;i<number.length;i++){ //j declared here for better scope
for(j=v.size();j>0 && v.get(j-1)>number[i] ;j--); //<-- some changes here,
v.add(j,number[i]); //<-- and here
}
}
for(int s:v)
System.out.print(s + " ");
}
}
The inner for loop is simply used to find the right index for an element to be inserted.
Your inner loop seems to not looping more than one time. That's why the key is not being inserted into right place.
A more concise solution would be
public class Test {
public static void main(String ar[]){
//Numbers to enter in vector
int[] number = {5,2,98,3,10,1};
Vector<Integer> v = new Vector<Integer>();
v.setSize(number.length);
v[0] = number[0];
for(int i=1, vSize = 1; i < number.length; i++, vSize++){
int j = 0, k = 0;
for(j = 0; j < vSize; j++) {
if(v[j] < number[i]) {
break;
}
for(k = vSize; k > j; k--) {
v[k] = v[k -1];
}
v[k] = number[i];
}
for(int s:v)
System.out.print(s + " ");
}
}

Reprint a String array Java

I have a string array
"Ben", "Jim", "Ken"
how can I print the above array 3 times to look like this:
"Ben", "Jim", "Ken"
"Jim", "Ben", "Ken"
"Ken", "Jim", "Ben"
I just want each item in the initial array to appear as the first element. The order the other items appear does not matter.
more examples
Input
"a","b","c","d"
output
"a","b","c","d"
"b","a","c","d"
"c","b","a","d"
"d","a","c","d"
Method signature
public void printArray(String[] s){
}
Rather than give you straight-up code, I'm going to try and explain the theory/mathematics for this problem.
The two easiest ways I can come up with to solve this problem is to either
Cycle through all the elements
Pick an element and list the rest
The first method would require you to iterate through the indices and then iterate through all the elements in the array and loop back to the beginning when necessary, terminating when you return to the original element.
The second method would require you to iterate through the indices, print original element, then proceed to iterate through the array from the beginning, skipping the original element.
As you can see, both these methods require two loops (as you are iterating through the array twice)
In pseudo code, the first method could be written as:
for (i = array_start; i < array_end; i++) {
print array_element[i]
for (j = i + 1; j != i; j++) {
if (j is_larger_than array_end) {
set j equal to array_start
}
print array_element[j]
}
}
In pseudo code, the second method could be written as:
for (i = array_start; i < array_end; i++) {
print array_element[i]
for (j = array_start; j < array_end; j++) {
if (j is_not_equal_to i) {
print array_element[j]
}
}
}
public void printArray(String[] s){
for (int i = 0; i < s.length; i++) {
System.out.print("\"" + s[i] + "\",");
for (int j = 0; j < s.length; j++) {
if (j != i) {
System.out.print("\"" + s[j] + "\",");
}
}
System.out.println();
}
}
This sounds like a homework question so while I feel I shouldn't answer it, I'll give a simple hint. You are looking for an algorithm which will give all permutations (combinations) of the "for loop index" of the elements not the elements themselves. so if you have three elements a,b,c them the index is 0,1,2 and all we need is a way to generate permutations of 0,1,2 so this leads to a common math problem with a very simple math formula.
See here: https://cbpowell.wordpress.com/2009/11/14/permutations-vs-combinations-how-to-calculate-arrangements/
for(int i=0;i<s.length;i++){
for(int j=i;j<s.length+i;j++) {
System.out.print(s[j%(s.length)]);
}
System.out.println();
}
Using mod is approppiate for this question. The indexes of the printed values for your first example are like this;
0 1 2
1 2 0
2 0 1
so if you write them like the following and take mod of length of the array (3 in this case) you will reach solution.
0 1 2
1 2 3
2 3 4

searching a 2D int[][] array?

How do I search a 2D array for a specific number (1)? I thought the following code did it, but apparently I was looking in a specific spot whenI declared it with [4][4].
boolean undirectedCircuit (int [][] graph)
{
//graph = graph1(graph1(null));
int edgeCounter = 0;
for (int edge = 0; edge < graph.length; edge++)
{
/* SET FOR WHEN 1s are found in array: edgeCounter++;*/
if(graph[4][4] == '1')
{
edgeCounter++;
System.out.println("edgeCounter found '1' " + edgeCounter + "times");
}
}
if (edgeCounter % 2 == 0)
{
System.out.println("This is a circuit!");
//return true;
}
else System.out.println("This is not a circuit!!");
return false;
}
public void go ()
{
graph1 = new int[][] //This line is complained about.
{
{0,1,1,1,0},
{1,0,0,0,1},
{1,0,0,1,0},
{1,0,1,0,1},
{0,1,0,1,0}
};
undirectedCircuit(graph1); //This is complained about.
}
This is part of an assignment from my school, just pointers would be great. Thank you!
This line is wrong in two ways:
if(graph[4][4] == '1')
The quotes around '1' make it a char literal. Since your array contains ints, you'll want to drop the quotes and just write 1.
graph[4][4] will always check the same value in the array as you said. Specifically, it will always access the fifth value in the fifth array of your 2d array. Whenever you write numbers in your code, they are constants: the number 4 is never going to change during your program's execution, so you keep using 4 as the index over and over again, accessing the fifth element each time you do so.
In order to access every element in an array, you can loop over it like this:
for (int n = 0; n < array.length; n ++)
{
array[n]; //access the nth element of the array
}
n in this instance is the same as your edge variable.
However, since you are using a 2d array, these elements are themselves arrays! Therefore, you need another loop:
//array is a 2d array...
for (int n = 0; n < array.length; n ++)
{
//...so its elements are 1d arrays
for (int m = 0; m < array[n].length; m ++)
{
array[m][n]; //here we have a specific object in our 2d array.
}
}
We use variables for our indices so they can change in the loop and access different values in the array. Hope this helps!
You could try something like this where you will iterate through both dimensions of the array and check your current location rather than the 4,4
for (int x = 0; x < graph.length; x++)
{
for (int y = 0; y < graph[x].length; y++)
{
/* SET FOR WHEN 1s are found in array: edgeCounter++;*/
if (graph[x][y] == 1)
{
edgeCounter++;
System.out.println("edgeCounter found '1' " + edgeCounter + "times");
}
}
}

trouble with arrays and array lists

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

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();
}
}

Categories

Resources