1

Please excuse me for my formatting mistakes as I am very new here. I have a Java assignment, in which I have to find the lexicographic lowest word that is larger then the given word from a scanner without putting the string in lexicographic order. In this example the given word is "am". I have written the code below but I have the problems that I will explain at the end of this question.

    public static void main (String[] args){
    Scanner s = new Scanner("I am very happy with life");

    String high = "";
    String o = "am";
    String curr = "";

    while (s.hasNext()){
        curr = s.next();
        if (curr.compareTo(high) > 0)
            high = curr;
    }

    Scanner ss = new Scanner("I am very happy with life");

    while (ss.hasNext()){
        curr = ss.next();
        if (curr.compareTo(high) < 0 && curr.compareTo(o) > 0)
            high = curr;
    }

    System.out.println(high);
}}

My problems are: I have to write a method that does the computation rather than having the procedure in main. Also I have to use the Scanner once and I can not initialize another scanner with the same value.

This code works ok, but I have the hardest times converting it into a single functional loop method.

PS. Sorry for stupid var names.

JungleJeem
  • 51
  • 8
  • 1
    Note, that you just need to fetch the words once from the scanner. If I understand the problem correctly, you are looking for the lexicographic lowest word that is larger then the given word. This can be done in one loop. – Henry Feb 12 '14 at 10:13
  • That is precisely what I am supposed to do. However I'm having the hardest time, writing a functional loop. – JungleJeem Feb 12 '14 at 10:16
  • I try not to give away the complete solution since you will learn more if you discover it yourself. Let me phrase it differently: among all the words that are larger than the given word you are looking for the minimum. – Henry Feb 12 '14 at 10:21
  • This is assignment was due 3 weeks ago! But I will try to figure this out. I have a test tomorrow, and this is really bugging me. – JungleJeem Feb 12 '14 at 10:23
  • Try to find a word 'greater' than the one given have but 'lower' than the one you had up to that point. I have the solution but I won't give it to you. – aalku Feb 12 '14 at 10:25
  • I would highly appreciate it if you can tell me how to code this. I have really tried my best to figure this thing out and finally stack has been my last resort. Please – JungleJeem Feb 12 '14 at 10:54

3 Answers3

2

Something like this (using a TreeSet):

import java.util.Scanner;
import java.util.TreeSet;

public class LexicographicScanner {

    private final TreeSet<String> words = new TreeSet<String>();

    public LexicographicScanner( final Scanner scanner )
    {
        while ( scanner.hasNext() )
        {
            words.add( scanner.next() );
        }
        scanner.close();
    }

    public String nextWord( final String word )
    {
        return words.higher( word );
    }

    public static void main(String[] args) {
        final LexicographicScanner ls
            = new LexicographicScanner ( new Scanner("I am very happy with life") );

        System.out.println( ls.nextWord( "am" ) );
        System.out.println( ls.nextWord( "I" ) );
        System.out.println( ls.nextWord( "with" ) );
    }
}

Output

happy
am
null

Edit

Without a TreeSet:

public class LexicographicScanner {

    public static String nextWord( final Scanner scanner, final String word )
    {
        String higher = null, curr;
        while ( scanner.hasNext() )
        {
            curr = scanner.next();
            if ( curr.compareTo( word ) > 0 )
            {
                if ( higher == null || curr.compareTo( higher ) < 0 )
                    higher = curr;
            }
        }
        return higher;
    }

    public static void main(String[] args) {
        final Scanner s1 = new Scanner("I am very happy with life");
        final Scanner s2 = new Scanner("I am very happy with life");
        final Scanner s3 = new Scanner("I am very happy with life");
        System.out.println( nextWord( s1, "am" ) );
        System.out.println( nextWord( s2, "I" ) );
        System.out.println( nextWord( s3, "with" ) );
        s1.close();
        s2.close();
        s3.close();
    }
}
MT0
  • 143,790
  • 11
  • 59
  • 117
  • I can not use a treeset because I am not allowed to put the string in lexicographic order. I should have mentioned that. Sorry! – JungleJeem Feb 12 '14 at 10:29
  • Thank you so much this works perfectly and I actually understand it. You made my day. Much love and respect. – JungleJeem Feb 12 '14 at 11:21
2

First make some requirements:

  1. The word i am looking for is lexicographic higher than my input word
  2. The word i am looking for is the lexicographic lowest possible

So basically you have to walk over your input sentence word for word and check those two requirements. Here is some pseudo code, i hope this helps to understand your problem/this solution.

inputWord <= input
currentlyHighest <= null

for (word <= sentence) {
    is word higher than inputWord?
        no: discard word and analyze the next one
        yes: go on

    do i have a currently highest word?
        no: save the word in currentlyHighest and analyze the next word
        yes: go on

    is word lower than currentlyHighest?
        no: discard word and analyze the next one
        yes: we have found a better match: save word in currentlyHighest and analyze the next one
}
Absurd-Mind
  • 7,884
  • 5
  • 35
  • 47
  • again, I understand the problem. but who would you make "word <= sentence" work in a single method? – JungleJeem Feb 12 '14 at 11:42
  • 1
    This is pseudocode, you already used a solution for this part in your code. But if you really insist, you could write: `for (String word : sentence.split("\\s+")) {}` – Absurd-Mind Feb 12 '14 at 11:59
1

Hint:

String res = null;
Scanner s = new Scanner(str);
for each curr in s scanner {
    if (curr greater than given
            and (dont have res or curr is less than res)) {
        res = curr;
    }
}
aalku
  • 2,860
  • 2
  • 23
  • 44
  • So someone gave me the answer, but I was trying to use your method because I really like for loops! but I was wondering how would you go about this? "for each curr in s scanner" Because I have to initialize an integer that equals the number of words in the sentence. For that I have to use a while loop to find that number. And then I can not use s.next() since there are no more words left. This solution would be a doable with two methods, correct? – JungleJeem Feb 12 '14 at 11:36
  • 1
    @JungleJeem nonono no. I meant 'for every word' but you don't need to use a for loop. Better use while. You had a solution in two steps and I am suggesting how you can join those loops in a single loop with compound criteria. Just look for a word greater than the given but less than any other found by now. You just have to carry the best word up to that point. – aalku Feb 12 '14 at 12:00
  • that makes sense. but this bring me to another question: How can I reiterate hasnext() or next() if I have already reached the end of my string and don't want to write another method? – JungleJeem Feb 12 '14 at 12:06
  • 1
    You don't. There is only one loop. In that loop you iterate over every word and examine it to decide if it is greater than the one given and it better than the one you have in the 'res' variable. – aalku Feb 12 '14 at 12:09