For now in my program i am using hard-coded values, but i want it so that the user can use any text file and get the same result.
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.File;
public class a1_12177903
{
public static void main(String [] args) throws IOException
{
if (args[0] == null)
{
System.out.println("File not found");
}
else
{
File file = new File(args[0]);
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
String line = "";
while (br.ready())
{
line += br.readLine();
}
String[] work = line.split(",");
double[] doubleArr = new double[work.length];
for (int i =0; i < doubleArr.length; i++)
{
doubleArr[i] = Double.parseDouble(work[i]);
}
double maxStartIndex=0;
double maxEndIndex=0;
double maxSum = 0;
double total = 0;
double maxStartIndexUntilNow = 0;
for (int currentIndex = 0; currentIndex < doubleArr.length; currentIndex++)
{
double eachArrayItem = doubleArr[currentIndex];
total += eachArrayItem;
if(total > maxSum)
{
maxSum = total;
maxStartIndex = maxStartIndexUntilNow;
maxEndIndex = currentIndex;
}
if (total < 0)
{
maxStartIndexUntilNow = currentIndex;
total = 0;
}
}
System.out.println("Max sum : "+ maxSum);
System.out.println("Max start index : "+ maxStartIndex);
System.out.println("Max end index : " +maxEndIndex);
}
}
}
I've fixed it so it takes in the name of the text file from the command line. if anyone has any ways to improve this, I'll happily accept any improvments.
You can do this with Java8 Streams, assuming each entry has it's own line
double[] doubleArr = Files.lines(pathToFile)
.mapToDouble(Double::valueOf)
.toArray();
If you were using this on production systems (rather than as an exercise) it would be worth while to create the Stream inside a Try with Resources block. This will make sure your input file is closed properly.
try(Stream<String> lines = Files.lines(path)){
doubleArr = stream.mapToDouble(Double::valueOf)
.toArray();
}
If you have a comma separated list, you will need to split them first and use a flatMap.
double[] doubleArr = Files.lines(pathToFile)
.flatMap(line->Stream.of(line.split(","))
.mapToDouble(Double::valueOf)
.toArray();
public static void main(String[] args) throws IOException {
String fileName = "";
File inputFile = new File(fileName);
BufferedReader br = new BufferedReader(new FileReader(inputFile));
// if input is in single line
StringTokenizer str = new StringTokenizer(br.readLine());
double[] intArr = new double[str.countTokens()];
for (int i = 0; i < str.countTokens(); i++) {
intArr[i] = Double.parseDouble(str.nextToken());
}
// if multiple lines in input file for a single case
String line = "";
ArrayList<Double> arryList = new ArrayList<>();
while ((line = br.readLine()) != null) {
// delimiter of your choice
for (String x : line.split(" ")) {
arryList.add(Double.parseDouble(x));
}
}
// convert arraylist to array or maybe process arrayList
}
This link may help: How to use BufferedReader. Then you will get a String containing the array.
Next you have several ways to analyze the string into an array.
Use JSONArray to parse it. For further information, search google for JSON.
Use the function split() to parse string to array. See below.
Code for way 2:
String line="10,20,50";//in fact you get this from file input.
String[] raw=line.split(",");
String[] arr=new String[raw.length];
for(int i=0;i<raw.length;++i)arr[i]=raw[i];
//now arr is what you want
Use streams if you are on JDK8. And please take care of design principles/patterns as well. It seems like a strategy/template design pattern can be applied here. I know, nobody here would ask you to focus on design guidelines.And also please take care of naming conventions. "File" as class name is not a good name.
Related
when there is a reading of lines and work with them continues line by line
I need to accept multi-line input first and only then to work the code
public class OrderRestaurant {
public static void main(String[] args) throws IOException {
InputStreamReader reader = new InputStreamReader(System.in, StandardCharsets.UTF_8);
BufferedReader in = new BufferedReader(reader);
String line = null;
TreeMap<String, LinkedList<Integer>> orderMap = new TreeMap<String, LinkedList<Integer>>();
Set<Integer> tableSet = new TreeSet<Integer>();
while ((line = in.readLine()) != null) {
String[] orders = line.split(",");
for (int i = 0; i < orders.length; i++) {
tableSet.add(Integer.parseInt(orders[1]));
}
if (!(orderMap.containsKey(orders[2]))) {
LinkedList<Integer> numbersTables = new LinkedList<>();
numbersTables.add(Integer.parseInt(orders[1]));
orderMap.put(orders[2], numbersTables);
} else {
orderMap.get(orders[2]).addLast(Integer.parseInt(orders[1]));
}
StringBuilder sBuilder = new StringBuilder("Table");
Set<String>keysOrderMapSet=orderMap.keySet();
for (String keyString : keysOrderMapSet) {
sBuilder.append(',').append(keyString);
}
for(Integer key : tableSet){
sBuilder.append("\n").append(key);
for(Map.Entry<String, LinkedList<Integer>> entry : orderMap.entrySet())
{
LinkedList<Integer> numbersOrder = entry.getValue();
int counterOrder = 0;
for (int i = 0; i < numbersOrder.size(); i++) {
if(numbersOrder.get(i)==key) {
counterOrder++;
}
}
sBuilder.append(',').append(counterOrder);
}
}
System.out.println(sBuilder.toString());
}
}
}
all input is green, further you can see that the output after the program runs is formed in parts and only at the end is displayed in its entirety.
What I understand from the question is that you want to read all lines from the console first then need to do any operation or work and after that, you want to print the result for each line on the console. If that is the case then you need to create an intermediate array or list to hold the data of each line. Please refer below steps:
Create an empty list as readLineByLineString that holds your input line by line.
Read line from the console using Scanner or BufferedReader.
Add that line to the list by readLineByLineString.add(line);
Read all the lines and add to the list until all test cases satisfy or required conditions.
Now you have all your data line by line in an intermediate list i.e. readLineByLineString, just do the required operation.
Print your result after each operation.
End
You can read for example 1024 bytes at a time.
char[] myBuffer = new char[512];
int bytesRead = 0;
BufferedReader in = new BufferedReader(new FileReader(reader));
while ((bytesRead = in.read(myBuffer,0,1024)) != -1)
{ ... }
Please I will like to adjust this code that reads integers from a file.
I will like the code to detect the number (n) of the dataset instead of having to put in figures manually as done below (4000 )
double[] tall = new double[4000];
public class Extracto {
public static void main(String[] args) throws IOException {
File fil = new File("C:\\Users\\Desktop\\kaycee2.csv");
FileReader inputFil = new FileReader(fil);
BufferedReader in = new BufferedReader(inputFil);
double[] tall = new double[4000];
String s = in.readLine();
int i = 0;
while (s != null) {
// Skip empty lines.
s = s.trim();
if (s.length() == 0) {
continue;
}
tall[i] = Double.parseDouble(s); // This is line 19.
// System.out.println(tall[i]);
s = in.readLine();
i++;
}
I am expecting the adjusted code to obtain the data length without manually putting it in like in as shown in the code below for the 4000 length.
double[] tall = new double[4000];
As Thomas mentioned, use a list, instead of an array.
File fil = new File("C:\\Users\\Desktop\\kaycee2.csv");
FileReader inputFil = new FileReader(fil);
BufferedReader in = new BufferedReader(inputFil);
ArrayList<Double> tall = new ArrayList<>();
while(in.ready()){
String s = in.readLine().trim();
if(!s.isEmpty()){
tall.add(Double.parseDouble(s);
}
}
your codes can be further compacted if you use a list.
also do add a try-catch in the event when the String read is not a number.
All I am trying to do is create an array from numbers in a file... I'm pretty new to java so it may not be the most efficient way but I'm going off limited knowledge for now.
When I run it, I get the following message:
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1540)
at CreateArray.main(CreateArray.java:27)
Here is my feeble attempt at the code:
import java.io.*;
import java.util.Scanner;
import java.util.ArrayList;
public class CreateArray
{
public static void main(String[] args) throws IOException
{
File file = new File("Numbers.txt");
Scanner inputFile = new Scanner(file);
// Find the number of lines in the file
int count = 0;
while (inputFile.hasNextLine())
{
String str = inputFile.nextLine();
count++;
}
// Create array
double[] numbers = new double[count];
// Add numbers to array
String str;
while (inputFile.hasNextLine());
{
for (int i = 0; i < count; i++)
{
str = inputFile.nextLine();
numbers[i] = Double.parseDouble(str);
}
}
// Display array
for (int i = 0; i < numbers.length; i++)
System.out.print(numbers[i] + " ");
}
}
When you write inputFile.hasNextLine() in your code using scanner, You have actually read a line from the file. As #tima said, you completed reading the file in the first while loop. Try looking at this java: about read txt file into array
Use Collection like ArrayList .So at time of File reading you don't need to declare size of array.
File file = new File("Numbers.txt");
Scanner inputFile = new Scanner(file);
List<Double> myList = new ArrayList<Double>();
while (inputFile.hasNextLine()) {
String str = inputFile.nextLine();
try {
myList.add(Double.parseDouble(str));
} catch (NumberFormatException e) {
// TODO: handle exception
}
}
for (Double data : myList) {
System.out.println(data);
}
And if you need array type ,then use this :-
Double data[] = new Double[myList.size()];
myList.toArray(data);
for (int i = 0; i < data.length; i++) {
System.out.println(data[i]);
}
I can read in from the file and am able to change the amount of lines given by changing the number in the for loop but I don't want all the numbers in my file displayed side by side like that. I need them all going down one by one randomly.
public class Assignment2 {
public static void main(String[] args) throws IOException
{
// Read in the file into a list of strings
BufferedReader reader = new BufferedReader(new FileReader("textfile.txt"));
List<String> lines = new ArrayList<String>();
String line = reader.readLine();
while( line != null ) {
lines.add(line);
line = reader.readLine();
}
// Choose a random one from the list
Random r = new Random();
for (int p = 0; p<3; p++)
{
String randomString = lines.get(r.nextInt(2));
System.out.println(lines);
}
}
}
I think what you want to print is
String randomString = lines.get(r.nextInt(2));
System.out.println(randomString);
To display only the first 20 random lines from this list of maybe 100
for (int i = 0; i < 20; i++) {
int rowNum = r.nextInt(lines.size ());
System.out.println(lines.get(rowNum);
}
First of, I don't know how a.db file stores it data. If it does it in one line, or over many lines. Probably it does some difference from how to solve the problem.
the problem I'm facing is that I don't know how much data the file contains, only that it will be a date, time, and a description for x number of events in the form given below.
I have to convert the text into strings and put them in an array, but I don't know how to separate the text. When I tried I just ended up with one long string.
Can anybody help me?
01.01.2015|07:00-07:15|get up
01.01.2015|08:00|get to work
01.01.2015|08:00-16:00| work
01.01.2015|16:00-16:30| go home
what I want:
array[0] = "01.01.2015|07:00-07:15|get up"
array[1] = "01.01.2015|08:00|get to work"
array[2] = "01.01.2015|08:00-16:00| work"
array[3] = "01.01.2015|16:00-16:30| go home"
string table[] = new String [100];
void readFile(String fileName){
String read = "";
try {
x = new Scanner (new File(fileName));
}
catch (Exception e) {
}
while (x.hasNext()) {
read += x.nextLine();
}
}
Assuming here that your first code-block is in fact a copy of the file you're trying to read, you can do:
Scanner s = new Scanner(new File("file1.txt"));
List<String> lines = new LinkedList<>();
while (s.hasNextLine())
lines.add(s.nextLine());
If you really want to work with arrays and not lists, you can do
String[] table = lines.toArray(new String[lines.size()]);
after the loop.
If you're fortunate enough to work with Java 8, you can use:
List<String> lines = Files.lines(Paths.get("big.txt"))
.collect(Collectors.toList());
Again, if you really want to work with an array, you can convert the list using lines.toArray.
Since Java 8 you can use Paths.get(String first, String... more), Files.lines(Path path), and Stream.toArray():
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class SOPlayground {
public static void main(String[] args) throws Exception {
Path path = Paths.get("/tmp", "db.txt");
Object[] lines = Files.lines(path).toArray();
System.out.println(lines.length);
System.out.println(lines[0]);
System.out.println(lines[lines.length - 1]);
}
}
Output:
4
01.01.2015|07:00-07:15|get up
01.01.2015|16:00-16:30| go home
Try this solution using arrays:
code
Scanner sc = new Scanner(new File("file.txt"));
int index;
String[] arr = new String[1];
for(index = 0; sc.hasNextLine(); index++) {
arr = Arrays.copyOf(arr, index + 1);
arr[index] = sc.nextLine();
}
for(int i = 0; i<arr.length; i++) {
System.out.print(arr[i] + "\n");
}
I have used arr = Arrays.copyOf(arr, index + 1) to increase the size of the array to add next element.
Output
01.01.2015|07:00-07:15|get up
01.01.2015|08:00|get to work
01.01.2015|08:00-16:00| work
01.01.2015|16:00-16:30| go home
Well, it took me some houres. Thanx to all who lended a hand. This was what I got in the end.
int i=0;
String array [] new String [100]
try {
FileReader textFileReader= new FileReader (fileName);
BufferedReader textReader= new BufferedReader(textFileReader);
boolean continue = true;
while (continue) {
String text = textReader.readLine();
if (text != null){
array[i] = text;
i++;
}else {
continue = false;
}
}
}catch (Exception e) {}