Adding digits within an arraylist with a guideline - java

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;

Related

Display the generated equation

I'm working on a school project in Android Studio and I've already asked here how to randomly generate equations, like 10+48*4. Someone suggested me this code to generate the equations:
String[] operationSet = new String[]{"+", "-", "/", "*"};
public void testGenerateRandomEquations() {
Random random = new Random();
int numOfOperations = random.nextInt(2) + 1;
List<String> operations = new ArrayList<>();
for (int i = 0; i < numOfOperations; i++) {
String operation = operationSet[random.nextInt(3)];
operations.add(operation);
}
int numOfNumbers = numOfOperations + 1;
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < numOfNumbers; i++) {
int number = random.nextInt(Integer.MAX_VALUE) - random.nextInt(Integer.MAX_VALUE);
numbers.add(number);
}
//Now you've the list of random numbers and operations. You can further randomize
//by randomly choosing the number and operation from those list.
}
But now I don't know how to display the generated equation. How can I display the equation for example in a TextView?
Maybe I'm just too dumb to understand but it would be nice if someone could help me :)
Here is the link to the original post: http://stackoverflow.com/a/39960279/6949270
All you have to do is to loop over the two lists - numbers and operations and concatenate them into a single string:
String equation = null;
for (int i = 0; i < numOfOperatrions; i++) {
equation += numbers.get(i);
equation += operations.get(i);
}
equation += numbers.get(numbers.size() -1); //Add the last number to the equation
The last line is needed because there are more numbers (one more) than operations.
It is better to use StringBuilder than String when concatenating strings, but for short strings it's OK.
EDIT - Why does it work?
We are concatenating String with an Integer, using the + operator.
The JAVA compiler converts in this case the Integer into a String, so no other casting is required.

Processing range of lines in a 2d array or file

I'm very new to programming. I'm studying on my own, and the examples from the book I'm using are too easy so I'm trying to do something harder. Lotteries are one of my hobbies and I think the problem I chose will make it easier for me to learn Java.
This program calculates frequencies (how many times each number from 1 t0 70 appears in my txt file) in Keno, a type of lottery(In Keno, a draw consists of 20 numbers out of 70, instead of the widespread 6 out of 49).
I want to calculate the frequencies not for the entire txt file, but just for a section of it, for example if the file has x lines, I want just the lines between x-5 and x-10, something like this.I don't know the number of lines in my file, perhaps thousands, but it always has 20 columns.
The program works fine for the entire file, but I run into trouble when trying to work just on a section of it. I think that I should read the file into a 2d array and then I could process the lines I want. I'm having hard times transferring every line into a matrix. I've read every post regarding reading a file into a 2d array but couldn't make it work.
Below is one of the many attempts I made over more than a week
public static void main(String args[]) {
int[][] matricea = new int [30][40];
int x=0, y=0;
try {
BufferedReader reader = new BufferedReader(
new FileReader("C:\\keno.txt")
);
int[] numbers = new int[72]; //each keno draw has 70 numbers
for (int i = 0; i < 71; i++ ){
numbers[i] = 0;
}
int k=0; // k counts the lines
String draw;
while ( (draw = reader.readLine()) != null ) {
String[] pieces = draw.split(" +");
k++;
for (String str : pieces) {
int str_int = Integer.parseInt(str);
matricea[x][y] = str_int;
System.out.print(matricea [x][y] + " ");
y = y + 1;
}
x = x + 1;
System.out.println(" ");
}
for (int j = 1; j <= 20; j++) {
int drawnNumber = Integer.parseInt(pieces[j]);
numbers[drawnNumber]++;
}
System.out.println(" nr. of lines is " + k);
reader.close();
for (int i = 0; i < 71; i++) {
System.out.println(i + ": " + numbers[i]);
}
} catch (Exception e) {
System.out.println("There was a problem opening and processing the file.");
}
}
Formatting and improving current code
I'll show how to solve your problem, but first I would like to point out a few things in your code that could be improved by some formatting, or that perhaps are unnecessary.
Just to help you improve your coding skills, readability is very important! :)
And don't forget, consistency is key! If you like one style better than the more common style, or the preferred style, that's fine as long as you use it throughout your coding. Don't switch between two styles.
If you don't care to read these comments, you can find the solution at the bottom of my answer. Just note that your original code will be different in my solution because I have formatted it to be most readable for me.
Spacing in variable declarations
Original code
int[][] matricea = new int [30][40];
int x=0, y=0;
Spacing modified
int[][] matricea = new int[30][40];
int x = 0, y = 0;
Notice the space removed between int and [30][40], and the space added between the variables and the initialization, i.e. - x=0 => x = 0.
Initializing an int array to contain all 0's
Original code
int[] numbers = new int[72]; //each keno draw has 70 numbers
for (int i = 0; i < 71; i++ ){
numbers[i] = 0;
}
Same as
int[] numbers = new int[72]; //each keno draw has 70 numbers
You don't have to set each value to 0, Java will do that for you. In fact, Java has default values, or null values, for all types. Thanks to Debosmit Ray!
I won't go into the exceptions to this case, or when or why or how, you can read about that in this post, and pay close attention to Aniket Thakur's answer.
But why do you have an array of size 72, if there are only 70 possibilities?
Choosing variable names
Original code
int k=0; // k counts the lines
Same as
int numLines = 0;
You should always make your variables names something meaningful to their purpose. If you ever have to put a comment like k counts the lines to describe a variable's purpose, consider if a better name would work instead.
Functionalizing code
Original code
while ( (draw = reader.readLine()) != null ) {
String[] pieces = draw.split(" +");
k++;
for (String str : pieces) {
int str_int = Integer.parseInt(str);
matricea[x][y] = str_int;
System.out.print(matricea [x][y] + " ");
y = y + 1;
}
x = x + 1;
System.out.println(" ");
}
Same as
while ( (draw = reader.readLine()) != null ) {
processLine(draw);
}
Of course, you'll have to make the method processLine(String line), but that won't be hard. It's just taking what you have and moving it to a separate method.
The original code's while loop is very busy and messy, but with the latter option makes the purpose clear, and the code clean.
Of course each situation is different, and you might find that only removing part of the code into a method would be a better solution. Just play around and see what makes sense.
Error!
Original code
for (int j = 1; j <= 20; j++) {
int drawnNumber = Integer.parseInt(pieces[j]);
numbers[drawnNumber]++;
}
This code should not work, since pieces is declared in the while loop above it, and is local to that above loop. This for loop is outside the scope of where pieces exists.
I'll tell you how to fix it, but I'm not sure what the code is supposed to be doing. Just let me know what its purpose is, and I'll provide you with a solution.
After formatting!
This is what the code may look like after applying my above comments. I have added comments to parts that I have changed.
public static void main(String args[]) {
try {
doKenoStuff();
} catch(IOException e) {
System.out.println("There was a problem opening and processing the file.");
}
}
public static void doKenoStuff() throws IOException {
BufferedReader reader = new BufferedReader(
new FileReader("C:\\keno.txt")
);
int[][] matricea = new int[30][40];
int[] numbers = new int[72]; //each keno draw has 70 numbers
// We can clean up our loop condition by removing
// the assignment (draw = reader.readLine) from it.
// Just make sure draw doesn't begin as null.
String draw = "";
int row;
for(row = 0; draw != null; row++) {
draw = reader.readLine();
// We read a line from the file, then send it
// to extractLineData which will collect the info
// from each column, and update matricea and numbers
extractLineData(draw, row, matricea, numbers);
}
System.out.println("Number of lines: " + row);
System.out.println("Each number's drawing stats:");
for (int i = 0; i < 71; i++) {
System.out.println(i + ": " + numbers[i]);
}
reader.close();
}
public static void extractLineData(String line, int row, int[][] matrix, int[] numbers) {
String linePieces = line.split(" +");
for(int column = 0; column < linePieces.length; column++) {
int number = Integer.parseInt(linePieces[column]);
matrix[row][column] = number;
numbers[number]++;
}
}
Solution
Note: I am not perfect, and my code is not either. I'm not trying to say that what I have suggested is in any way the only way to do this. It could definitely be improved, but it is a start. You should take my solution and see how you can improve it yourself.
What can you find that you could code in a cleaner, or faster, or better way?
So, how do we fix the problem?
We have a method that reads from the start of a file, to the end of it, and it logs the data it finds inside matricea.
A quick and easy solution is to simply make that method take in two parameters, a starting line number, and an ending line number.
public static void doKenoStuff(int start, int end) throws IOException {
Then we simply make a loop to skip over the starting lines! It's that easy!!!
for(int i = 0; i < start - 1; i++) {
reader.readLine();
}
Don't forget that we may not need the big 30 row matricea to be 30 rows anymore. We can shrink that down to end - start + 1. That way, if a user wants to read from line 45 to line 45, we only need 45 - 45 + 1 = 1 row in matricea.
int[][] matricea = new int[end - start + 1][40];
And the very last thing we need to add is a condition in our line reading loop, that prevents us from going past the ending line.
for(row = 0; draw != null, row <= end; row++) {
And there you have it. Simple as that!
Complete solution
public static void main(String args[]) {
int start = 7, end = 18;
try {
doKenoStuff(start, end);
} catch(IOException e) {
System.out.println("There was a problem opening and processing the file.");
}
}
public static void doKenoStuff(int start, int end) throws IOException {
BufferedReader reader = new BufferedReader(
new FileReader("C:\\keno.txt")
);
int[][] matricea = new int[end - start + 1][40];
int[] numbers = new int[72]; //each keno draw has 70 numbers
for(int i = 0; i < start - 1; i++) {
reader.readLine();
}
String draw = "";
int row;
for(row = 0; draw != null, row <= end; row++) {
draw = reader.readLine();
extractLineData(draw, row, matricea, numbers);
}
System.out.println("Number of lines: " + row);
System.out.println("Each number's drawing stats:");
for (int i = 0; i < 71; i++) {
System.out.println(i + ": " + numbers[i]);
}
reader.close();
}
public static void extractLineData(String line, int row, int[][] matrix, int[] numbers) {
String linePieces = line.split(" +");
for(int column = 0; column < linePieces.length; column++) {
try {
int number = Integer.parseInt(linePieces[column]);
matrix[row][column] = number;
numbers[number]++;
} catch (NumberFormatException) {
// You don't have to do anything in this block, but
// you can print out what input gave the exception if you want.
System.out.println("Bad input: \"" + linePieces[column] + "\"");
}
}
}

Split a String Twice

Not sure if my mind is just numb or I am just stupid, but for some reason the logic behind this escapes me. Essentially in an android app I am pulling CSV information through a PHP script. That information gets displayed like
value00,value01,value02,value03,value04;value10,value11,value12,value13,value14;value20, etc...
now I want to set up a two dimensional array where thisArray[0][0] = value00, thisArray[1][1] = value11, thisArray[1][4] = value14, etc. The code I have will split by the ";" but I can't figure out how to then split that array into a two dimensional array set up the way I want. This is what I have: (httpMessage is the string containing the above information)
String[][] secondSplit;//
String[] firstSplit;//
String currvalue;//
firstSplit = httpMessage.split(";");
for(int i=0; i<firstSplit.length; i++) {
Log.d("EFFs" + Integer.toString(i),firstSplit[i]);
}
LogCat shows the desired behavior, EFFs0 = line 1, EFFs1 = line 2, just the way I want it. But now, how do I get that second dimension? Also, since I am 100% sure this is a dumb question with an easy answer I'll throw in another, is there an easy way to tell if a string is a number?
You could do the following:
secondSplit = new String[firstSplit.length][];
for(int i=0; i<firstSplit.length; i++){
secondSplit[i] = firstSplit[i].split(",");
}
Pretty sure that would work. Let me know if it doesn't! Hope that helps!
If you know how many rows and columns there are you can use the Scanner class like this (recently learned this from this answer):
Scanner sc = new Scanner(input).useDelimiter("[,;]");
final int M = 5;
final int N = 2;
String[][] matrix = new String[M][N];
for (int r = 0; r < M; r++) {
for (int c = 0; c < N; c++) {
matrix[r][c] = sc.next();
}
}
//Just to see that it worked
for(String[] row : matrix) {
for(String col : row) {
System.out.print(col+",");
}
System.out.println();
}

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

convert line from text file into variables 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.

Categories

Resources