convert line from text file into variables JAVA - java

I'm trying to extract the numbers individual lines from a text file and perform an operation on them and print them to a new text file.
my text file reads somethings like
10 2 5 2
10 2 5 3
etc...
Id like to do some serious math so Id like to be able to call upon each number from the line I'm working with and put it into a calculation.
It seems like an array would be the best thing to use for this, but to get the numbers into an array do I have to use a string tokenizer?

Scanner sc = new Scanner(new File("mynums.txt"));
while(sc.hasNextLine()) {
String[] numstrs = sc.nextLine().split("\\s+"); // split by white space
int[] nums = new int[numstrs.length];
for(int i = 0; i < nums.length; i++) nums[i] = Integer.parseInt(numstrs[i]);
// now you can manipulate the numbers in nums[]
}
Obviously you don't have to use an int[] nums. You can instead do
int x = Integer.parseInt(numstrs[0]);
int m = Integer.parseInt(numstrs[1]);
int b = Integer.parseInt(numstrs[2]);
int y = m*x + b; // or something? :-)
Alternatively, if you know the structure ahead of time to be all ints, you could do something like this:
List<Integer> ints = new ArrayList<Integer>();
Scanner sc = new Scanner(new File("mynums.txt"));
while(sc.hasNextInt()) {
ints.add(sc.nextInt());
}
It creates Integer objects which is less desirable, but isn't significantly expensive these days. You can always convert it to an int[] after you slurp them in.

Related

Adding digits within an arraylist with a guideline

I'm a newbie coder and in need some help. Im trying to add the digits of a number together according to a number corresponding to how many digits I can use. Im using Eclipse Juno and using a separate text file for using my numbers. Though it isn't much This is what I have now:
public static void main(String[] args) throws IOException{
String token1 = "";
Scanner infile1 = new Scanner(new File("input.txt"));
ArrayList<String> temps = new ArrayList<String>();
//Adding Input files to the Arraylist
while(infile1.hasNext()){
token1 = infile1.next();
temps.add(token1);
}
infile1.close();
//Calling the Numbers from ArrrayList temps
for(int x = 0; x < temps.size(); x++) {
System.out.println(x + " " + temps.get(x));
for(x = 0; x < temps.size(); x++ ){
}
}
}
}
The numbers are
9678415 7,
9678415 6,
9678415 5,
9678415 4,
2678515 3,
Number to add, digits to use. The input.txt file does not have commas
Exactly how you do this is going to depend on what the data looks like in the file. You say it's not delimited by commas so I will have to assume they are separated by lines. You will need to separate the values within the strings and convert to int; so the below should do what you are attempting, if I understand the question. (full disclosure, it's been a little while since I've written in Java and I don't have a way to test this right now, make sure I haven't made any basic syntax errors)
ArrayList<Integer> totalArray = ArrayList<Integer>();
for(String tStr : temps){
int tempTotal = 0;
String[] numArray = tStr.split(" ");
for(int x = 0; x < Integer.parseInt(numArray[1]){
int y = Integer.parseInt(numArray[0].substring(x,x+1));
tempTotal += y;
}
totalArray.add(tempTotal);
}
There are probably better ways to get the highest value, but since I have been out of this for a little while, I'm just going to do it in the most basic way I can think of.
int highestValue = 0;
for (Integer x : totalArray){
if(highestValue<=x){
highestValue = x;
}
}
return highestValue;

Getting rid of auto-filled zeroes in 2d Java array

The user inputs numbers with a max of 20 per line and 50 lines. The problem is that if the user inputs less than 20 integers on a line, the array is filled with zeros in the empty spaces so that there is 20 total. This impacts my calculations done with the array.
Does anyone know of an efficient way to get rid of those zeros so that only the original inputted numbers remain?
//Extracting/reading from file
public void readFile(File file) {
try {
//creates scanner to read file
Scanner scn = new Scanner(file);
//set initial count (of rows) to zero
int maxrows = 0;
//sets columns to 20 (every row has 20 integers - filled w zeros if not 20 inputted)
int maxcolumns = 20;
// goes through file and counts number of rows to set array parameter for length
while (scn.hasNextLine()) {
maxrows++;
scn.nextLine();
}
// create array of counted size
int[][] array = new int[maxrows][maxcolumns];
//new scanner to reset (read file from beginning again)
Scanner scn2 = new Scanner(file);
//places integers one by one into array
for (int row = 0; row < maxrows; row++) {
Scanner lineScan = new Scanner(scn2.nextLine());
//checks if row has integers
if (lineScan.hasNextInt()) {
for (int column = 0; lineScan.hasNextInt(); column++) {
array[row][column] = Integer.parseInt(lineScan.next());
}
} else System.out.println("ERROR: Row " + (row + 1) + " has no integers.");
}
rawData = array;
}
}
You should look into Lists instead. Since you admit that you don't know how many elements are going to be inserted, we can simply grow out the list with however many things the user wants to add.
// Initialize the initial capacity of your dataMatrix to "maxRows",
// which is NOT a hard restriction on the size of the list
List<List<Integer>> dataMatrix = new ArrayList<>(maxrows);
// When you want to add new elements to that, you must create a new `List` first...
for (int row = 0 ; row < maxrows ; row++) {
if (lineScan.hasNextInt()) {
List<Integer> matrixRow = new ArrayList<>();
for (int column = 0; lineScan.hasNextInt(); column++) {
dataMatrix.add(Integer.parseInt(lineScan.next()));
}
// ...then add the list to your dataMatrix.
dataMatrix.add(matrixRow);
}
}
As mentioned in Java labguage Specifications, all the elements of array will be initialized with '0' value if array is of type int.
However, if you want to differentiate between 0 that is input by user and 0 that is assigned by default, I would recommend using array of Integer class so that all the values are initialized with null, although that would need changing in code (i.e. to check for null value before casting it in int literal), e.g:
Integer[][] array = new Integer[maxrows][maxcolumns];
In that case you cany create ArrayList of ArrayList instead of 2d Arrays.
ArrayList<ArrayList<Integer>> group = new ArrayList<ArrayList<Integer>>(maxrows);
Now you can dynamicaly assign value based on input values, so no extra zero added to data if it contains less than 20 in a row.
I usually use ArrayList<Integer>s when I need a varying number of integers.
If you must have an array, either set everything to -1 (if -1 is an invalid/sentinel input), or count how many times the user inputs numbers. Then you'd just need to stop when you reach the -1, or exceed the number of inputs.

How can a stream be used to calculate the sum of an array that receives input?

I am new to programming with arrays, so I am not sure how I can calculate the sum of an array that receives input. Through research, I've learned how to set up an array and how to calculate the sum of the array using stream, but when the array receives input (such that it does not start with a set value), I do not know how to calculate the sum. Here is my code:
public class TestClass {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
ArrayList a = new ArrayList();
for (int i = 0; i < 20; ++i){
double b = sc.nextDouble();
a.add(b);
int[] c = a;//This step is where I get lost. I'm not sure what needs to happen to a
Arrays.stream(c);
System.out.println(Arrays.stream(c).sum());
}
}
}
Thanks
Note: java.util.*, java.io.*, java.util.stream.*, and java.util.Arrays are all imported.
You think think about your task first. You are asking the scanner for double values and at a later time you want an int[] array. This doesn’t match.
As said by others, there is no need for an array, if you want to sum up the values as double, declare the list as List<Double> to clarify this. Then you can simply stream the list to sum it up like list.stream().reduce(Double::sum).orElse(0) or list.stream().mapToDouble(Double::doubleValue).sum().
However, if you are only interested in the sum, there is no need for a list at all:
Scanner sc = new Scanner(System.in);
double sum=0;
for (int i = 0; i < 20; ++i) {
sum += sc.nextDouble();
System.out.println(sum);
}
has the same effect. It doesn’t use a Stream but there wouldn’t be any benefit from using streams.
If you want to solve the task “sum up twenty input values” via Stream you may consider omitting the intermediate sums. In that case, there is a clean solution:
Scanner sc = new Scanner(System.in);
double sum=DoubleStream.generate(sc::nextDouble).limit(20).sum();
System.out.println(sum);
You can use reduce in conjunction with Double::sum:
Scanner sc = new Scanner(System.in);
List<Double> arr = new ArrayList<>(); // Use generics - never use raw types!
for (int i = 0; i < 20; ++i) {
Double b = sc.nextDouble();
arr.add(b);
sc.nextLine(); // <-- add this line in order to be able to feed numbers manually
}
Double res = arr.stream().reduce(Double::sum).get();
System.out.println(res);
As a variation of the theme presented by alfasin, you can specialise the Stream as a DoubleStream and utilise the sum method on it.
List<Double> arr = new ArrayList<>();
... enrol the numbers ...
double sum = arr.stream().mapToDouble(d -> d).sum();
As mentioned by Jean-François Savard, you should be aware that that your original List has been changed to List<Double> in this solution. If you want to know why, read up on Generics.

Capturing Integers from Strings in Java

I'm attempting to capture integers from a user input using Scanner. These integers represent coordinates and a radius between 0 and 1000. It's a circle on a 2D plane.
What I have to do is to somehow capture these integers separately from one line. So, for example, the user inputs
5 100 20
Therefore, the x-coordinate is 5, the y-coordinate is 100, and the radius is 20.
The user must input all of these values on the same line, and I have to somehow capture the values from the program into three different variables.
So, I tried using this:
Scanner input = new Scanner(System.in);
String coordAndRadius = input.nextLine();
int x = coordAndRadius.charAt(0); // x-coordinate of ship
int y = coordAndRadius.charAt(2); // y-coordinate of ship
int r = coordAndRadius.charAt(4); // radius of ship
for one-digit characters, as a test. Didn't turn out so well.
Any suggestions?
Well the easiest way (not the nicest one) is just split them into array using String methods :
public static void filesInFolder(String filename) {
Scanner input = new Scanner(System.in);
String coordAndRadius = input.nextLine();
String[] array = coordAndRadius.split(" ");
int x = Integer.valueOf(array[0]);
int y = Integer.valueOf(array[1]);
int r = Integer.valueOf(array[2]);
}
You can also use nextInt method, which looks like this :
public static void filesInFolder(String filename) {
Scanner input = new Scanner(System.in);
int[] data = new int[3];
for (int i = 0; i < data.length; i++) {
data[i] = input.nextInt();
}
}
Your input will be stored in array data
Create a string array using coordAndRadius.split(" "); and extract the values from each array element.
You must split the input into 3 different string variables, each of which can be parsed separately. Use the split method to return an array, with each element containing a piece of input.
String[] fields = coordAndRadius.split(" "); // Split by space
Then you can parse each piece into an int using Integer.parseInt:
int x = Integer.parseInt(fields[0]);
// likewise for y and r
Just make sure you have 3 elements in your array before accessing it.
try this:
Scanner scanner = new Scanner(System.in);
System.out.println("Provide x, y and radius,");
int x = scanner.nextInt();
int y = scanner.nextInt();
int radius = scanner.nextInt();
System.out.println("Your x:"+x+" y: "+y+" radius:"+radius);
It will work either you will type in "10 20 24" or "10\n20\n24" where \n is of course a newline character.
And just in case you would like to know why your approach does not work here is explanation.
int x = coordAndRadius.charAt(0);
charAt(0) return first character of your string which then gets implicitly casted into int. Assume your coordAndRadius ="10 20 24". So in this case first char is '1'. So the statement above can be written as:
int x = (int)'1';
Split the values by space
String[] values = coordAndRadius.split(" ");
Then get each value as int using Integer.parseInt:
int x = Integer.parseInt(values[0]);
int y = Integer.parseInt(values[1]);
int radious = Integer.parseInt(values[2]);

two dimensional arraylists and input/sorting

I am trying to add all the doubles between two <end> instances into an arraylist within an arraylist (at each index of <end> have the doubles between the <end>s, and so forth)
ArrayList<ArrayList<Double>> myArr = new ArrayList<ArrayList<Double>>();
int j = 0;
int nLine = 0;
while(scan.hasNext()) {
String line = scan.next();
//System.out.println(line);
if(!line.equals("<end>")) {
nLine = Double.valueOf(line);
ArrayList<Double> row = new ArrayList<Double>();
myArr.add(row);
row.add(j, nLine);
j=j++;
} else {
j=j++;
}
}
As it stands now the code is putting in a single double in a an array (as opposed to all of the ones between statements; thus the output looks like this:
[[1.4], [3], [15], [3.2], etc. etc.
where I want it to look like this:
[[1.4, 3, 15, 3.2], [5, 13.4], [954.3, etc....
The file it is scanning is essentially:
<end>
1.4
3
15
3.2
<end>
5
13.4
<end>
954.3
43 etc. etc. (infinitely)
My goal (eventually) is to tally how many doubles are in each arrayList index and make sure none of the doubles are exactly the same, and to make sure each of the row arrays have no more than 10 values in them.
So I have been stuck and any help is appreciated.
Thanks for any help.
ArrayList<ArrayList<Double>> myArr = new ArrayList<ArrayList<Double>>();
int nLine = 0;
ArrayList<Double> currArr = null;
while(scan.hasNext()) {
String line = scan.next();
if(!line.equals("<end>")) {
nLine = Integer.valueOf(line);
currArr.add(nLine);
} else {
if(currArr!=null) myArr.add(currArr);
currArr = new ArrayList<Double>();
}
}
if(currArr!=null) myArr.add(currArr);
In the middle of the code you're using Integer instead of Double. Not sure why so I left it. Code assumes the input always starts with <end>.
You could use a HashSet as a way to keep track of the duplicates (or better yet use an ArrayList of Sets instead to avoid the extra data structure)
Here's an example of generating a random # of ArrayLists without dups:
ArrayList<ArrayList<Integer>> myArr = new ArrayList<ArrayList<Integer>>();
HashSet<Integer> duplicates = new HashSet<Integer>();
Random random = new Random();
for(int x=0; x<3; x++) {
ArrayList<Integer> row = new ArrayList<Integer>();
myArr.add(row);
for(int y=0; y<3; y++) {
int randomInt = random.nextInt(100);
if(!duplicates.contains(randomInt)) {
row.add(0,randomInt);
duplicates.add(randomInt);
}
}
}
for(int i=0;i<myArr.size();i++)
{
System.out.println(myArr.get(i));
}

Categories

Resources