3

I'm trying to write a Java program to analyse each string in a string array from a text file and if the number parses to a double, the program prints the word previous to it and the word after. I can't seem to find out how to parse each element of a string array. Currently it will only print the first number and the following word but not the previous word. Hopefully somebody can help.

My text file is as follows:

Suppose 49 are slicing a cake to divide it between 5 people. I cut myself a big slice, consisting of 33.3 percent of the whole cake. Now it is your turn to cut a slice of cake. Will you also cut a 33.3 percent slice? Or will you be fairer and divide the remaining 66.6 percent of the cake into 4 even parts? How big a slice will you cut?

Here is my code:

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

import javax.swing.JOptionPane;


public class NumberSearch {

public static void main(String args[]) throws FileNotFoundException {

    //creating File instance to reference text file in Java
//    String filedirect = JOptionPane.showInputDialog(null, "Enter your file"); 
    File text = new File("cakeQuestion2.txt");

    //Creating Scanner instance to read File in Java

    Scanner scnr = new Scanner(text);

    //Reading each line of file using Scanner class
    int lineNumber = 1;
    while(scnr.hasNextLine())
    {

        String line = scnr.nextLine();
        lineNumber++; 

//Finding words


           String[] sp = line.split(" +"); // "+" for multiple spaces

            for (int i = 1; i < sp.length; i++) 

            {
                {

               double d = Double.parseDouble(sp[i]);
//                   System.out.println(+ d);

               if (isDouble(sp[i]))

                {
                    // have to check for ArrayIndexOutOfBoundsException
                    String surr = (i-2 > 0 ? " " + sp[i-2]+" " : "") +
                                  sp[i] +
                                  (i+1 < sp.length ? " "+sp[i+1] : "");


                    System.out.println(surr);
                }

            }}
        }

    }

    public static boolean isDouble( String str )
    {
        try{
            Double.parseDouble( str );
            return true;
        }
        catch( Exception e ){
            return false;
        }}} 
Gavin Coll
  • 89
  • 1
  • 1
  • 11
  • I think using try catch will be costly operation. follow this [link](http://stackoverflow.com/questions/3543729/how-to-check-that-a-string-is-parseable-to-a-double). using `regex` will be more elegant. – seal Nov 07 '16 at 15:16
  • 4
    `String surr = (i-2 > 0 ? " " + sp[i-2]+" " : "") + sp[i] + (i+1 < sp.length ? " "+sp[i+1] : "");` The purpose of the ternary operator is to help with readability. You need to break this out into individual bits with a StringBuilder, because it is not that easy to read. – Compass Nov 07 '16 at 15:17
  • one obvious mistake i see is the for loop condition. You need to start loop with int i=0; – vinay Nov 07 '16 at 15:19
  • `parseDouble` is not enugh, as 20 will parse to double, but it's an integer not a double, either use regex as Seal suggest, or use different approach. one more thing the check-for-index code is ugly, +1 for compass, and i think `i-2` should be `i-1` as you may mean prev word, its 1 step back not 2, right ? – Yazan Nov 07 '16 at 15:19
  • @vinay yes, now i know why op used i-2 for prev word?! – Yazan Nov 07 '16 at 15:19

1 Answers1

3

Mmmmm... your code seems too verbose and complex for the mission.

Check this snippet:

public static void main(String args[]) throws FileNotFoundException {
    String line = "Suppose 49 are slicing a cake to divide it between 5 people. I cut myself a big slice, consisting of 33.3 percent of the whole cake. Now it is your turn to cut a slice of cake. Will you also cut a 33.3 percent slice? Or will you be fairer and divide the remaining 66.6 percent of the cake into 4 even parts? How big a slice will you cut?";
    String[] sp = line.split(" +"); // "+" for multiple spaces
    final String SPACE = " "; 

    // loop over the data
    for (int i = 0; i < sp.length; i++) {
        try {
            // if exception is not raised, IS A DOUBLE!
            Double.parseDouble(sp[i]);

            // if is not first position print previous word (avoid negative index)
            if (i > 0)
                System.out.print(sp[i - 1] + SPACE);

            // print number itself
            System.out.print(sp[i] + SPACE);

            // if is not last position print previous word (avoid IOOBE)
            if (i < sp.length - 1)
                System.out.print(sp[i + 1]);

            // next line!
            System.out.println();
        } catch (NumberFormatException ex) {
            // if is not a number, not our problem!
        }
    }
}

RESULT:

Suppose 49 are
between 5 people.
of 33.3 percent
a 33.3 percent
remaining 66.6 percent
into 4 even
Jordi Castilla
  • 26,609
  • 8
  • 70
  • 109
  • for loop should start from 0 ? – Yazan Nov 07 '16 at 15:25
  • 1
    @Ma3x what if first word is 45.6 ? is it still extra work? – Yazan Nov 07 '16 at 15:27
  • 2
    in this single case is an extra iteration, if the data is dynamically retrieved, YES. – Jordi Castilla Nov 07 '16 at 15:27
  • `Double.parseDouble(sp[i]);` is not enough? `Double.parseDouble(30);` will pass but it's not double? – Yazan Nov 07 '16 at 15:27
  • It is nearly there. The desired output would be, for example: 'Suppose 49 are' or ' a 33.3 percent' – Gavin Coll Nov 07 '16 at 15:27
  • 1
    @GavinColl you solved your problem?? As long as **you never marked an answer as accepted** in [any of your questions](http://stackoverflow.com/users/5873343/gavin-coll?tab=questions) you must know if this or any answer has solved your question please consider accepting it by clicking the check-mark. This indicates to the wider community that you've found a solution and gives some reputation to both the answerer and yourself. There is no obligation to do this. – Jordi Castilla Nov 07 '16 at 16:30
  • @JordiCastilla Thanks very much! I wasn't aware of this. I will do that now – Gavin Coll Nov 08 '16 at 12:09
  • @GavinColl glad to help, this is the way Stack Exchange works, is great to help future users know which answer worked for you, in this case it's only one answer, but in questions like [**this one**](http://stackoverflow.com/questions/35537803/how-do-i-avoid-two-sentences-with-the-same-first-letter-being-beside-each-other) with 4 answers is more useful (also reputation points are great `;P`) – Jordi Castilla Nov 08 '16 at 12:14