Java - Treat data from a file - java

I have a file that looks like this:
year population
1952 120323
1953 136688
1954 161681
.... .....
I want to go in that find the year with the largest increase in population as compared to the previous year.
I tried th following code but I get a the NoSuchElementException and I'm not sure why:
String path = "filePath";
File file = new File(filePath);
Scanner sc = new Scanner(file);
int y = 0, y1, y2, p1, p2, diff = 0;
while(sc.hasNext()){
if(sc.next().equals("year") || sc.next().equals("population")){
break;
}else{
y1 = Integer.parseInt(sc.next());
p1 = Integer.parseInt(sc.next());
y2 = Integer.parseInt(sc.next()); // this line throws the exception
p2 = Integer.parseInt(sc.next());
if(p2 - p1 > diff){
diff = y2-y1;
y = y2;
}
}
}
System.out.println(y);

Not sure how your code produced NoSuchElementException error. Because you are exiting from the loop when you find "year" or "population". Hope the following code should meet your expected result.
String path = "filePath";
File file = new File (path);
Scanner scanner = new Scanner(file);
Long[][] yd = new Long[0][];
long prev = 0;
for(scanner.nextLine();scanner.hasNext();){
long year = scanner.nextLong();
long curnt = scanner.nextLong();
long diff = prev==0?prev:curnt-prev;
prev = curnt;
yd = Arrays.copyOf(yd, yd.length+1);
yd[yd.length-1] = new Long[2];
yd[yd.length-1][0] = year;
yd[yd.length-1][1] = diff;
}
Arrays.sort(yd, new Comparator<Long[]>() {
#Override
public int compare(Long[] o1, Long[] o2) {
Long diffOne = o1[1];
Long diffTwo = o2[1];
return diffTwo.compareTo(diffOne);
}
});
System.out.println("Year="+yd[0][0]+"; Difference="+yd[0][1]);

Try this...
String path = "filePath";
File file = new File (filePath);
Scanner sc = new Scanner(file);
long year = 0L, population = 0L, largestDiff = 0L;
while (sc.hasNext()) {
String line = sc.nextLine();
if (line.startsWith("year")) {
continue;
} else {
String[] parts = line.split(" +"); // Note the space before "+"
long currentYear = Long.parseLong(parts[0]);
long currentPopulation = Long.parseLong(parts[1]);
long diff = currentPopulation - population;
if (dif > largestDiff) {
largestDiff = diff;
year = currentYear;
}
population = currentPopulation;
}
}
System.out.println(year);
System.out.println(largestDiff);

Related

String Split and operation

public static void clacMethod() {
int result = 0;
// int i;
System.out.println("Enter numbers to calculation");
String input = new Scanner(System.in).nextLine();
String[] inputSplit = new String[input.length()];
int[] output = new int[inputSplit.length];
for (int i = 0; i < inputSplit.length; i++) {
if (input.contains("-")) {
inputSplit = input.split("\\-");
output[i] = Integer.parseInt(inputSplit[i]);
result = output[0];
result -= output[i];
}
if (input.contains("+")) {
inputSplit = input.split("\\+");
output[i] = Integer.parseInt(inputSplit[i]);
result = output[0];
result = result + output[i];
}
}
System.out.println(result);
}
how i have to work
How it have to work "+" and "-" operations on String input
// input should be like: 12+10-4
// output should be: 18
if is not a school exercise use ScripEnginer
public double calc(String input) {
int result;
ScriptEngineManager sem= new ScriptEngineManager();
ScriptEngine engine = sem.getEngineByName("JavaScript");
result = (Double)engine.eval(input)
return result;
}
where input is a String "12+10-4"
and result will be a double 8

Using scanner and file to compute a mean score from a .csv file (java)?

Use Scanner and File to read this file of vocabulary scores as measured by the General Social Survey from 1972 to 2004. Compute and display the mean score for both males and females.
I am unsure of how to seperate the lines into chunks by comma and to still retain the correct data.
Example of what the file contains:
Female,7
Male,3
Male,6
Male,10
Female,10
public static void main(String[] args) throws FileNotFoundException {
File file = new File("scores.csv");
Scanner in = new Scanner(file);
String run = "";
int maleCount = 0;
int femaleCount = 0;
int maleScore = 0;
int femaleScore = 0;
while (in.hasNextLine()) {
String current = in.nextLine();
in.useDelimiter(",");
if (current.contains("f")) {
femaleCount++;
// add score onto femaleScore
}
else {
maleCount++;
// add score onto maleScore
}
double femaleAverage = femaleScore / femaleCount;
System.out.println(femaleAverage);
double maleAverage = maleScore / maleCount;
System.out.println(maleAverage);
}
in.close();
}
Your calculation was inside the while loop, meaning it would calculate this average once per line in the file, which is wrong.
The code below assumes the format of the data is the same as stated in your post.
Female,7
Male,3
Male,6
Male,10
Female,10
public static void main(String[] args) throws FileNotFoundException {
File file = new File("scores.csv");
Scanner in = new Scanner(file);
String run = "";
int maleCount = 0;
int femaleCount = 0;
int maleScore = 0;
int femaleScore = 0;
while (in.hasNextLine()) {
String current = in.nextLine();
String[] split = current.split(",");
if (split[0].toLowerCase().contains("f")) {
femaleCount++;
femaleScore += Integer.parseInt(split[1]);
// add score onto femaleScore
} else {
maleCount++;
maleScore += Integer.parseInt(split[1]);
// add score onto maleScore
}
}
double femaleAverage = femaleScore / femaleCount;
System.out.println(femaleAverage);
double maleAverage = maleScore / maleCount;
System.out.println(maleAverage);
in.close();
}
If the data is different, post it here and I will edit the code accordingly
Assuming your input file is structured as below:
male, 4
female, 7
male, 3
female, 5
etc
Then the below code should do what you want. You were pretty close, just had to split the line's on commas and then assess the parts (gender/score) like array.
String filePath = "C:\\Users\\adam\\Documents\\Scores.txt";
File file = new File(filePath);
Scanner scanner = new Scanner(file);
int maleCount = 0;
int femaleCount = 0;
int maleScore= 0;
int femaleScore = 0;
while(scanner.hasNext()){
String line = scanner.nextLine();
String[] split = line.split(",");
String gender = split[0];
String score = split[1];
if(gender.toLowerCase().trim().equals("male")){
maleCount++;
maleScore += Integer.valueOf(score.trim());
}else if(gender.toLowerCase().trim().equals("female")){
femaleCount++;
femaleScore += Integer.valueOf(score.trim());
}
}
scanner.close();
double maleAverage = (double) maleScore / maleCount;
double femaleAverage = (double) femaleScore / femaleCount;
System.out.println("Male Average: " + maleAverage);
System.out.println("Female Average: " + femaleAverage);

JAVA :Unable to view println after the while loop

I'm unable to view the println after exiting the "For" and "While" loop.
What am i doing wrong?
Assignment is : to Extract doubles from a txt file that has the numbers split by a "," . once i have the data do some calculations and display it. I've done all except the displaying. which I'm having some difficulty in.
try {
FileInputStream ofile = new FileInputStream("Sales Analysis.txt");
DataInputStream in = new DataInputStream(ofile);
BufferedReader Rreader = new BufferedReader( new InputStreamReader(in));
String Filedata ;
String read;
double[] TotalWeekSales = new double [7];
double[] DailyAverage = new double [7];
double TotalSales = 0;
double[] amount= new double [7];
double AverageSales = 0;
int Topsale = -1 ; // Position of Highest Week Sale
int LowestSale= -1; // Lowest Week Sale
while ((Filedata= Rreader.readLine()) != null) {
String[] Splitt = Filedata.split(",");
//double amount[] =new double [10];
for (int i = 0; i<Filedata.length(); i++)
{
read = Splitt[i];
amount[i] = Double.parseDouble(read);
TotalWeekSales[i] = amount[i];
DailyAverage[i]= (amount[i]/7);
TotalSales += amount[i];
System.out.println("\nWeek: "+(i+1));
System.out.println("\nAmount : $"+amount[i]);
}
};
/********* This part below doesn't Print ***********/
AverageSales = (TotalSales/7);
System.out.println("\nTotal Average Sales: $"+AverageSales);
} catch (Exception e) {
// TODO: handle exception
}
}
}
for (int i = 0; i<Filedata.length(); i++)
should be:
for (int i = 0; i < Splitt.length; i++)
there might be other bugs as well.
Note: it's difficult to read the code since it's not indented properly.

Android long text pagination

I have a need to display large text files. Display text without the need to scroll as an e-book. I can break a long text on the page, but it takes me too much time. For example - the following code handles 1.4 MB of text for about 10-15 seconds.
public void split(TextPaint textPaint, String filepath,Context context) {
int pages = 0;
File file = new File(filepath);
char[] bufferChar = new char[1024];
String uncompletedtext="";
//How lines we can show
int maxLinesOnpage = 0;
StaticLayout staticLayout = new StaticLayout(
context.getString(R.string.lorem_ipsum),
textPaint,
pageWidth,
Layout.Alignment.ALIGN_NORMAL,
lineSpacingMultiplier,
lineSpacingExtra,
false
);
int startLineTop = staticLayout.getLineTop(0);
int endLine = staticLayout.getLineForVertical(startLineTop + pageHeight);
int endLineBottom = staticLayout.getLineBottom(endLine);
if (endLineBottom > startLineTop + pageHeight) {
maxLinesOnpage = endLine - 1;
} else {
maxLinesOnpage = endLine;
}
//let's paginate
try {
BufferedReader buffer = new BufferedReader(new FileReader(file));
while (buffer.read(bufferChar)>=0) {
uncompletedtext += new String(bufferChar);
boolean allcomplete = false;
staticLayout = new StaticLayout(
uncompletedtext,
textPaint,
pageWidth,
Layout.Alignment.ALIGN_NORMAL,
lineSpacingMultiplier,
lineSpacingExtra,
false
);
staticLayout.getLineCount();
int curTextPages= (int) Math.floor(staticLayout.getLineCount() / maxLinesOnpage);
uncompletedtext=uncompletedtext.substring(staticLayout.getLineEnd(curTextPages));
pages+=curTextPages;
Log.e("PAGES","" + pages);
}
} catch (Exception e) {
e.printStackTrace();
}
Log.e("FILE READED FULLY!!", "READ COMPLETE!!!!!!!!!!!!!!!!");
}
It is too long. I can not understand how applications such as FBReader and СoolReader handle large files (More than 9 MB) instantly.
I saw the source of the applications, but they have too much functionality to quickly find answer.
I really need help and tips. Thanks.
Thanks to all! I find solution! Not elegant but very fast code (10Mb ~ 600 ms)
public void split(TextPaint textPaint, String filepath,Context context) {
File file = new File(filepath);
char[] bufferChar = new char[512];
//How lines on page
int maxLinesOnpage = 0;
int symbolsOnLine = 0;
StaticLayout staticLayout = new StaticLayout(
context.getString(R.string.lorem_ipsum),//short text with 100 lines (\r\n\r\n\r\n\r\n\r\n\r\n)
textPaint, //MONOSPACE!!!
pageWidth,
Layout.Alignment.ALIGN_NORMAL,
lineSpacingMultiplier,
lineSpacingExtra,
false
);
int startLineTop = staticLayout.getLineTop(0);
int endLine = staticLayout.getLineForVertical(startLineTop + pageHeight);
int endLineBottom = staticLayout.getLineBottom(endLine);
if (endLineBottom > startLineTop + pageHeight) {
maxLinesOnpage = endLine - 1;
} else {
maxLinesOnpage = endLine;
}
symbolsOnLine = staticLayout.getLineEnd(0);
try {
RandomAccessFile rac = new RandomAccessFile(file, "r");
byte[] buffer = new byte[2048];
int wordLen = 0; //Length of word in symbols
int wordInBytes = 0; //Lenght of word
int startLinePos = 0; //Start first line position
int lineWidth = 0; //Current line length
int totalLines =0; //Total lines on current page
Log.e("Start pagination", "" + totalLines);
long timeout= System.currentTimeMillis();
int buflen=0; //buffer size
int totalReadedBytes = 0; //Total bytes readed
byte skipBytes = 0;
while ( (buflen=rac.read(buffer))!=-1){
for (int i=0;i<buflen;i++) {
totalReadedBytes++;
wordInBytes++;
if (skipBytes==0){ //Bytes on one symbol
if (unsignedToBytes(buffer[i])>=192){skipBytes=2;}
if (unsignedToBytes(buffer[i])>=224){skipBytes=3;}
if (unsignedToBytes(buffer[i])>=240){skipBytes=4;}
if (unsignedToBytes(buffer[i])>=248){skipBytes=5;}
if (unsignedToBytes(buffer[i])>=252){skipBytes=6;}
}
//Full bytes on symbol or not
if (skipBytes>0){
skipBytes--;
if (skipBytes>0){continue;}
}
if (buffer[i] == 13) {//We have a \r symbol. Ignore.
continue;
}
if (buffer[i]==10){//New line symbol
if (lineWidth + wordLen>symbolsOnLine){
totalLines++;
if (totalLines > maxLinesOnpage) {
int[] pgsbytes = {startLinePos, totalReadedBytes};
pages.add(pgsbytes);
startLinePos = totalReadedBytes ;
totalLines = 0;
}
}
wordLen=0;
wordInBytes=0;
totalLines++;
lineWidth=0;
if (totalLines>maxLinesOnpage){
int[] pgsbytes = {startLinePos, totalReadedBytes-1};
pages.add(pgsbytes);
startLinePos = totalReadedBytes-1;
totalLines=0;
}
}
if (buffer[i]==32){//Space symbol
if (lineWidth + wordLen+1<=symbolsOnLine){//Word fits in line
lineWidth+=wordLen + 1;
wordLen=0;
if (lineWidth==symbolsOnLine){
totalLines++;
if (totalLines > maxLinesOnpage) {
int[] pgsbytes = {startLinePos, totalReadedBytes};
pages.add(pgsbytes);
startLinePos = totalReadedBytes ;
totalLines = 0;
}
lineWidth = 0;
wordLen = 0;
wordInBytes=0;
}
} else {
if (lineWidth + wordLen==symbolsOnLine){
totalLines++;
if (totalLines > maxLinesOnpage) {
int[] pgsbytes = {startLinePos, totalReadedBytes};
pages.add(pgsbytes);
startLinePos = totalReadedBytes ;
totalLines = 0;
}
lineWidth = 0;
wordLen = 0;
wordInBytes=0;
} else {
totalLines++;
if (totalLines > maxLinesOnpage) {
int[] pgsbytes = {startLinePos, totalReadedBytes - 1 - wordInBytes};
pages.add(pgsbytes);
startLinePos = totalReadedBytes - 1;
totalLines = 0;
}
lineWidth = wordLen + 1;
wordLen = 0;
wordInBytes=0;
}
}
}
if (buffer[i]!=32&&buffer[i]!=10&&buffer[i]!=13){wordLen++; }
if (wordLen==symbolsOnLine){
totalLines++;
if (totalLines>maxLinesOnpage){
int[] pgsbytes = {startLinePos, totalReadedBytes-1 - wordInBytes};
pages.add(pgsbytes);
startLinePos = totalReadedBytes-1;
totalLines=0;
}
lineWidth=0;
wordLen=0;
wordInBytes=0;
}
}
}
rac.close();
timeout = System.currentTimeMillis() - timeout;
Log.e("TOTAL Time", " time " + timeout + "ms");
} catch (Exception e) {
e.printStackTrace();
}
Log.e("FILE READED FULLY!!", "READ COMPLETE!!!!!!!!!!!!!!!!");
}

Convert the string "8:00" into the minutes (integer value)

I'm reading the data from CSV file. One of the fields is the time in the format H:mm, i.e. "8:00". How to convert this string value into the minutes (integer value), i.e. 8:00 = 8*60 = 480 minutes?
String csvFilename = "test.csv";
CSVReader csvReader = new CSVReader(new FileReader(csvFilename));
String[] row = null;
csvReader.readNext(); // to skip the headers
int i = 0;
while((row = csvReader.readNext()) != null) {
int open = Integer.parseInt(row[0]);
}
csvReader.close();
You can use java.text.SimpleDateFormat to convert String to Date. And then java.util.Calendar to extract hours and minutes.
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
Date date = sdf.parse("8:00");
cal.setTime(date);
int mins = cal.get(Calendar.HOUR)*60 + cal.get(Calendar.MINUTE);
Try something like this
String str = "8:10";
int minutes=0;
String[] arr= str.split(":");
if(arr.length==2){
minutes=Integer.parseInt(arr[0])*60+Integer.parseInt(arr[1]);
}
System.out.println(minutes);
Write something like this to convert into int
public int convertToMin(String hrmin) {
String[] tokens = hrmin.split(":");
int minutes = 0;
for (int i = tokens.length; i > 0; i--) {
int value = Integer.parseInt(tokens[i - 1]);
if (i == 1) {
minutes += 60 * value;
}
else {
minutes += value;
}
}
return minutes;
}
Try this
String str = "8:20";
int ans = (Integer.parseInt(str.split(":")[0])* 60)+Integer.parseInt(str.split(":")[1]);
System.out.println("Answer = "+ans);

Categories

Resources