Removing the first element of an array without using in java - java

i'm trying to read a line in a file and store it in an array, after doing this i want to remove the first element in the array so that the length can be 1 element less and make the length of the array same as another array so i can match both arrays using for loop. the line i want to read from the file is
"London 2 7 24 16 -15 8 27"
try {
File myObj = new File("temperatures.txt");
FileReader read = new FileReader(myObj);
Scanner myReader = new Scanner(myObj);
Scanner input = new Scanner(System.in);
LineNumberReader lines = new LineNumberReader(read);
lines.skip(Long.MAX_VALUE);
int len = lines.getLineNumber();
int count = len;
String ans;
for (int i = 0; i < len && myReader.hasNextLine();i++){
System.out.println(count+" Cities temperature left!");
System.out.print("Do you want to check temperature details; enter y or n: ");
ans = input.nextLine();
if(ans.equals("y")){
String[] getData = myReader.nextLine().split(" ");
String[] days = {"Mon", "Tue", "Weds", "Thurs", "Fri", "Sat", "Sun"};
for (int j = 0; j < getData.length; j++){
System.out.println(days[j]+": "+getData[j]);
}
}
else{
}
}
} catch (FileNotFoundException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}

There are several possible solutions to your problem.
Not deleting the element at all
You can iterate 2 arrays in parallel like this:
for (int j = 0; j < days.length; j++) {
System.out.println(days[j] + ": " + getData[j + 1]);
}
As you can see, we start and index 0 with days, but we start at 1 with getData. This will work, because you know that getData is exactly one element bigger than days. Also, note that the condition of the loop changed to j < days.length. This is because days is shorter and so we should iterate through the shorter array. Alternatively, you can write j < getData.length - 1.
Creating a copy
There is no way to delete an element from an array. You have to construct a new array.
String[] newData = new String[getData.length - 1];
for (int j = 0; j < newData.length; j++) {
newData[j] = getData[j + 1];
}
Then you can use newData instead of getData to print the numbers.
Use a collection or a stream
I won't go into the details, but you can construct a collection (e.g. an ArrayList) from your array, delete the first element from the list (because unlike arrays, you can actually delete elements of lists), and then iterate the list (no need to create another array). Or, you can create a stream from an array, skip the first element (streams have the skip method), and copy the stream into an array.
But as for me, this way is overkill for such a simple task. I think that even creating a copy is a bit too much. You're better off just using the first solution, it's the easiest one.

Why not add +1 to the index value of getData[] in the loop?
System.out.println(days[j] + ": " +getData[j+1]);

Related

Java arrayList for loop index out of bounds when combining two arrays of different length

I'm just learning java and working on a homework problem. Our assignment was two read two-word lists into arrays and then combine them into one ArrayList alternating the words in the list. e.g. L1[0], L2[0], L1[1], L2[1], etc.
I've got my code almost running EXCEPT if the word lists are not exactly the same length, I either leave off the last words in the long list or get an out-of-bounds index for the shorter list.
I know there must be an obvious solution I haven't thought of. Thanks for your help!
Here is the code I've written:
public class ArrayMixer {
public static void main (String[] args){
Scanner scnr= new Scanner(System.in); // set up scanner
// Initialize variables to capture user inputs
String firstLine;
String secondLine;
//collect user input for the first list
System.out.println("Please enter the first word list:"); // prompt user for first list
firstLine= scnr.nextLine();
String[] firstArray= firstLine.split(" "); // creates array to store first line split by spaces
//System.out.println(firstLine);//FIXME COMMENT OUT AFTER TESTING
//System.out.println(Arrays.toString(firstArray));//FIXME COMMENT OUT AFTER TESTING
//collect user input for the second list
System.out.println("Please enter the second word list:");// prompt user for second list
secondLine= scnr.nextLine();//
String[] secArray= secondLine.split(" ");//create array to store second list split by spaces
//System.out.println(secondLine);//FIXME COMMENT OUT
//System.out.println(Arrays.toString(secArray)); //FIXME COMMENT OUT
//Create an array list called mixList to store combination of list 1 and 2
ArrayList <String> mixList = new ArrayList<String>();
// need to find out size of two lists put together
int mixSize= (firstArray.length + secArray.length);
System.out.println(mixSize);
//HERE IS MY PROBLEM I've replace secArray.length w/ mxSize, and firstArray.length NO DICE
for (int i=0; i< secArray.length; ++i) {//FIXME NEED TO FIGURE OUT HOW TO GET THE LOOP
// NOT GO OUT OF BOUNDS
mixList.add(firstArray[i]);
mixList.add(secArray[i]);
}
//print new list to output
for (int i=0; i< mixList.size(); ++i) {
String tempWord=mixList.get(i);
System.out.println(tempWord);
}
}
}
I've tried using the length of the two lists combined and the length of the longer list-> index out of bounds, the shorter list- last words of the longer list left off because the loop never gets to their index.
Is there some sort of special arrayList for loop I can use?
final String[] firstArray = firstLine.split(" ");
final String[] secondArray = secondLine.split(" ");
final List<String> mixList = new ArrayList<>();
final int largerArray = Math.max(firstArray.length, secondArray.length);
for (int i = 0; i < largerArray; i++) {
if (i < firstArray.length) {
mixList.add(firstArray[i]);
}
if (i < secondArray.length) {
mixList.add(secondArray[i]);
}
}
Here is one way to combine them. You will need to adapt this to your specific requirements.
List<Integer> evens = List.of(2, 4, 6, 8, 10, 12);
List<Integer> odds = List.of(1, 3, 5);
List<Integer> combined = new ArrayList<>();
for (int i = 0, k = 0; i + k < evens.size() + odds.size(); ) {
if (i < odds.size()) {
combined.add(odds.get(i++));
}
if (k < evens.size()) {
combined.add(evens.get(k++));
}
}
System.out.println(combined);
And here is another.
for (int i = 0; i < Math.max(odds.size(), evens.size()); i++) {
if (i < odds.size()) {
combined.add(odds.get(i));
}
if (i < evens.size()) {
combined.add(evens.get(i));
}
}
System.out.println(combined);
both print
[1, 2, 3, 4, 5, 6, 8, 10, 12]
I would do it exactly like Dreamspace President's answer. I think it should be the accepted one.
However, I would at least like to propose an alternative approach.
The reasoning behind this is that the new list was expected to contain alternating entries from the original arrays. If one array is much shorter than the other one, the result would only start with alternating values but end with just the "rest" of the larger array.
If this was unwanted behavior, you could also stop processing the arrays:
You already saw the exception, and you know that it will definitely be thrown when you are dealing with arrays that have different lengths. So you could also catch the exception and jump out of the loop:
final int largerArray = Math.max(firstArray.length, secondArray.length);
for (int i = 0; i < largerArray; i++) {
try {
mixList.add(firstArray[i]);
mixList.add(secondArray[i]);
} catch (IndexOutOfBoundsException e) {
// one array is longer than the other, we cannot alternate any longer
// -> jumping out of the loop
break;
}
}
Thanks for your help everyone!
Here is the solution I ended up on.
ArrayList <String> mixList = new ArrayList<String>();
// This scenario accounts for a shorter first list of words
if (firstArray.length < secArray.length) {
// This alternates the words until first list is exhausted
for (int i = 0; i < firstArray.length; ++i) {
mixList.add(firstArray[i]);
mixList.add(secArray[i]);
}
//this adds the remaining words from the longer list on to the end
for (int i = firstArray.length; i < secArray.length; ++i) {
mixList.add(secArray[i]);
}
}
//This accounts for when the second list is shorter or if they are the same length
else {
// This alternates the words until second list is exhausted
for (int i = 0; i < secArray.length; ++i) {
mixList.add(firstArray[i]);
mixList.add(secArray[i]);
}
//this adds the remaining words from the longer list on to the end
//If lists are the same length, the list will not execute
for ( int i = secArray.length; i < firstArray.length; ++i) {
mixList.add(firstArray[i]);
}
}
//print new list to output
for (int i=0; i< mixList.size(); ++i) {
String tempWord=mixList.get(i);
System.out.println(tempWord);
}

How do you take a 2D array from a text file, and "copy" it into another array using charAt

I was working through a project and I have to use charAt to continuously add elements of an array from a text file to a new array that i would have specified. The size of the array differs depending on the text file being used so it is best to assume that the contents of the file are unknown, however i will provide an example.
I keep on getting a "StringIndexOutOfBoundException" when i run my code and i am not sure why, or how to fix it.
What the code should be doing is taking the user input to get the exact text file location, then it will be reading that line by line and adding that to a new array. The first two lines of the text file array are the array row and column size.
my code is as follows:
public static void main(String[] args) throws FileNotFoundException
{
System.out.println("Enter the location of the board file using the FULL PATH NAME.");
Scanner input = new Scanner(System.in);
String n = input.nextLine();
input.close();
File a = new File(n);
Scanner sc = new Scanner(a);
int row = sc.nextInt();
int col = sc.nextInt();
char[][] board = new char[row][col];
for (int numRow = 0; numRow < row+1; numRow ++)
{
String string = sc.next();
for (int numCol = 0; numCol < col+1; numCol++)
{
board[row][col] = string.charAt(numCol);
}
}
sc.close();
GridGame game = new GridGame (row, col, board);
game.playGame();
An example input text file:
10 10
EEEEEEEEES
SWWWWWWWWW
EEEEEEEEES
SWWWWWWWWW
EEEEEEEEES
SWWWWWWWWW
EEEEEEEEES
SWWWWWWWWW
EEEEEEEEES
TWWWWWWWWW
The issue you are facing is because a Java array has 0-based index i.e. the index of the first element is 0 and that of the last element is array.length - 1. Therefore, your loop with the variable as the index of the array should not go beyond array.length - 1. Your terminating condition, numRow < row+1 is taking the value of numRow up to the length of the array instead of array.length - 1.
Replace
for (int numRow = 0; numRow < row+1; numRow ++)
{
String string = sc.next();
for (int numCol = 0; numCol < col+1; numCol++)
{
board[row][col] = string.charAt(numCol);
}
}
with
for (int r = 0; r < row && sc.hasNextLine(); r++) {
board[r] = sc.nextLine().toCharArray();
}
The other concept you need to understand is a 2-D array in Java an array of arrays i.e. board[0] should hold the array of characters from the first line of the file, board[1] should hold the array of characters from the second line of the file and so on. Now, if you want to access the 4th character of the 3rd line from the file, you can access it as board[2][3].
The last but not the least is regarding closing the Scanner for System.in. You should never close this Scanner because it also closes the System.in. So, you should remove the line, input.close() from your code.
Update
You can write the above mentioned single loop as a nested loop as well but it is unnecessary.
for (int r = 0; r < row && sc.hasNextLine(); r++) {
char[] lineChars = sc.nextLine().toCharArray();
for(int c = 0; c < col; c++) {
board[r][c] = lineChars [c];
}
}
You need a nested loop in order to access/process individual characters but to store/access/process each row of a 2-D array, you do not need a nested loop. As I have already mentioned, a 2-D array is an array of 1-D arrays and therefore to access each of these 1-D arrays (not individual elements inside these 1-D arrays), you need a single loop, not a nested loop.

How to store data in a string array using java collection

I have stored data in a List<String[]> and need to store those data into an another String array using a loop. I have created a String array (value) and stored data in there but the issue is first element is getting replaced by second inside the loop and it will show only the last element at the end of the loop.
CSVReader reader = new CSVReader(new FileReader(csvfile));
List<String[]> data = reader.readAll();
String[] values = new String[5];
for (int i = 1; i < 5; i++) {
values = data.get(i);
System.out.println(values[1]); // data is getting replaced here
}
System.out.println(values[1]); // this will show only the last stored value
Lists are 0 indexed so unless you intentionally want to skip the first element then don't start the loop iteration at 1 rather at 0.
Yes, when performing the last println after the loop only data related to the last String[] is shown because at each iteration you're updating values i.e. values = data.get(i); to store the current String[] hence the aforementioned outcome.
You probably want a String[][] as opposed to String[] because each String[] represents a line of the file.
Thus, assuming you only want to get the first five lines from data you can do it as:
String[][] lines = data.subList(0, 5).toArray(String[][]::new);
or for all the lines read:
String[][] lines = reader.readAll().toArray(String[][]::new);
and you can test it with:
System.out.println(Arrays.deepToString(lines));
// generating data
List<String[]> data =
Stream.iterate(0, n -> n + 1)
.limit(10)
.map(i -> new String[]{"a" + i, "b" + i, "c" + i, "d" + i, "e" + i, "f" + i})
.collect(Collectors.toList());
String[][] values = new String[data.size()][];
// copy the data
for (int i = 0; i < data.size(); i++)
{
values[i] = data.get(i).clone();
}
//print the result
Arrays.stream(values).map(Arrays::toString).forEach(System.out::println);
Replace :
for (int i = 1; i < 5; i++) {
values = data.get(i);
System.out.println(values[1]); // data is getting replaced here}
With:
for (int i = 0; i < 5; i++) {
values = data.get(i);
System.out.println(values[1]); // data is getting replaced here}
I think you have a little error inside the for loop. Try this:
CSVReader reader = new CSVReader(new FileReader(csvfile));
List<String[]> data = reader.readAll();
String[] values = new String[5];
for (int i = 1; i < 5; i++) {
values[i] = data.get(i);
System.out.println(values[1]); // data is getting replaced here
}
System.out.println(values[1]); // this will show only the last stored value
I think you are missing the "[i]" at the first line inside the for loop.
Your data variable contains a list of String[] (string arrays). Your for loop is attempting to store them in values which is a single String[].
Depending on what you are trying to do, you can do as the comments suggest and make a 2D String array. However, the fact that you want to remove them from a perfectly good list of String[]'s leads me to believe you probably want them in one big String[].
Below is an example of how to put the first N (in this case 5) words you parse from the csv into the values variable. However, we would be able to give you better guidance if you provided what the ultimate use case of your code snippet is.
// initialize test data
List<String[]> data = new ArrayList<String[]>();
String[] a = {"a1", "a2"};
String[] b = {"b1", "b2"};
String[] c = {"c1", "c2"};
data.add(a);
data.add(b);
data.add(c);
// big N is how many words you want
int N = 5;
// little n tracks how many words have been collected
int n = 0;
String[] values = new String[N];
// loop through csv collect
for (int i = 0; i < data.size(); i++){
String[] cur = data.get(i);
// loop through the strings in each list entry
for (int j = 0; j < cur.length; j++){
// store value and increment counter
values[n] = cur[j];
n++;
// stop if maximum words have been reached
if (n >= N)
break;
}
// stop if maximum words have been reached
if (n >= N)
break;
}
for (int i = 0; i < values.length; i++)
System.out.println(values[i]);

Java loop output keep on repeating

String[] month = {"Jan","Feb","Mar","Apr","May","June","July","Aug","Sept","Oct","Nov","Dec"};
int[] monthArray = new int[12];
String[][] itemArray = new String[12][10];
Variables
monthArray[i] = input.nextInt();
itemArray[monthArray[i]-1][e] = input.next();
Store a maximum of 5 String values on user input's month.
for(int i=0;i<e;e++){
System.out.println(itemArray[monthArray[i]-1][i]);
}
Having a problem displaying the String values (it just keep repeating the first String value) under user input's month.
You are increasing e instead of i in the last loop. e is the limit and not the variable you use for the iteration and thus the loop will not terminate until you overflow int.
for(int i = 0; i < e; i++ /* Note the usage of i here*/) {
use i++ instead of e++
here e stands for the limit
and i stands for the variable.
Since you have a 2D array, maybe you want something more like this, to print out the values, once, the array has been populated.
String[][] itemArray = new String[12][10];
for(int i = 0; i < itemAreray.length; i++){
for (int j = 0; j < itemArray[i].legnth; j++){
System.out.println(itemArray[i][j]);
}
}
Unless you're having difficulty populating the array. Then that's a different problem

Iterating through ArrayList to get 5 Largest Numbers

Yes, this is homework, but I need some help with it. I have been able to make it sort through the highest number, but none of the numbers are correct after that. List of numbers: http://pastebin.com/Ss1WFGv1
Right now, we are learning arrays, so is this simply trying to shoot a fly with a cannonball?
package hw2;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
public class HW2 {
public static ArrayList<Integer> nums1 = new ArrayList<Integer>();
public static int size = 0;
public static void main(String[] args) throws Exception {
ArrayList<Integer> sortedNums = new ArrayList<Integer>();
readFile();
System.out.println("Name: Jay Bhagat" + "\n" + "Email: xxxxxx");
size = nums1.size();
for(int l = 0; l<=10;l++){
nums1.set(sortThis(nums1, l), 90009);
System.out.println("\n\n");
}
// for (int k = 0; k <= size - 1; k++) {
// System.out.println("Number " + (k + 1) + sortedNums.get(k));
//
// }
}
public static void readFile() throws Exception {
BufferedReader reader = new BufferedReader(new FileReader("L:\\numbers.txt"));
while (reader.readLine() != null) {
nums1.add(Integer.parseInt((reader.readLine())));
}
reader.close();
}
public static int sortThis(ArrayList<Integer> current, int offset) {
int j = 0;
int tempNum = 0;
int curNum = 0;
int finalIndex = 0;
int prevIndex = 0;
int curIndex = 0;
for (j = 0; j < size-offset; j++) {
curIndex = j;
nums1.trimToSize();
curNum = current.get(j);
//Thread.sleep(1000);
if(curNum!=90009){
if (curNum > tempNum) {
tempNum = curNum;
System.out.println(tempNum);
prevIndex = j;
finalIndex = prevIndex;
}
if (curNum < tempNum) {
finalIndex = prevIndex;
}
}
}
return finalIndex;
}
}
An approach that lets you make just one pass through the list and doesn't require sorting:
Declare an array of 5 integers: int[] largest = new int[5];
Put the first 5 elements in the ArrayList into largest.
Starting with the 6th element, look at each element N in the ArrayList, and if N is larger than any element in largest, throw out the smallest number currently in largest and replace it with N.
If you need to exclude duplicates, the algorithm can be modified easily (just skip over any ArrayList element that's already in largest).
Why not use Collections.sort(List list) or Arrays.Sort(arr). This will save much of effort. Or is it part of your task?
Assuming your collection is sorted, and you want the last 5 elements, try this out:
for (int i = sortedNums.size() - 5; i < sortedNums.size(); ++i) {
System.err.println(sortedNums.get(i));
}
How I would go about doing this:
Create a temporary ArrayList, as a copy of the initial one.
After each largest element is found, remove it from the temporary ArrayList and add it to your 5 largest numbers
Repeat until complete
edit* This does not require your elements to be sorted, and has a fairly poor efficiency as a result
I assume you do not have the liberty to use sort and suchlike, considering this is a homework. So here is outline of an algorithm that you can try to implement
create an array of five integers (we will keep this sorted)
for each element in the list
find the index of the element in the array that it is greater than
if no such element exists in the array (i.e. it is smaller than all elements in the array)
continue on to the next element in the list
else
push all elements in the array to one index below, letting them fall off the
edge if need be (e.g. if the number in list is 42 and the array has
45 and 40 at index 3 and 2 respectively then
move arr[1] to arr[0], and arr[2] (40) to arr[1] and set arr[2] = 42)
end if
end for
At the end the array will have the five elements
I will leave one question for you to answer (it is important): what should you set the array to initially?
You only need two lines of code:
Collections.sort(nums1);
List<Integer> high5 = nums1.subList(nums1.size() - 5, nums1.size());
If you must "do it yourself", the simplest way to sort is a bubble sort:
iterate over the list
swap adjacent numbers if they are in the wrong order
repeat n times
Not efficient but very easy to code.

Categories