5

As usual, I'm just another highschooler desperate enough to resort to asking the question after lots of googling.

I'm working on one of them programs that can somewhat be applied in real life (but never are). In this case, a change counter that sums up the number of dimes, nickels, quarters and remaining cents and shows them in one sentence.

My problem is, I need to make a proper sentence format that uses commas and an "and" in the end, which I can't manage with my very limited current knowledge.

  • Anywhere you see a division of currency is a variable that represents it (cents, dimes etc)
  • backupInput is the variable that holds the user's chosen number of cents (anything from 1-100)

The part of my program concerned with what I want to ask is this:

    System.out.print(backupInput + ": ");

    // Outputting the quarters
    if (quarters > 0)
    {
      if (quarters == 1)
        System.out.print("one quarter, ");
      else
        System.out.print(quarters + " quarters, ");
    }

    // Outputting the dimes
    if (dimes > 0)
    {
      if (dimes == 1)
        System.out.print("one dime, ");
      else
        System.out.print(dimes + " dimes, ");
    }  

    // Outputting the nickels
    if (nickels > 0)
    {
      if (nickels == 1)
        System.out.print("one nickel, ");
      else
        System.out.print(nickels + " nickels ");
    }

    // Outputting the cents
    if (cents > 0)
    {
      if (cents == 1)
        System.out.print(" one cent");
      else
        System.out.print(cents + " cents ");
    }

The problem is, anything this outputs give the result of something like

7: 1 dime, 2 cents

While it's supposed to be, according to the example format given:

7: 1 dime and 2 cents
65: 2 quarters, 1 dime and one nickel
66: 2 quarters, 1 dime, 1 nickel, and one cent

Keep in mind I tried nearly everything I could think of and in all my tries it was too inefficient and didn't even work in all the cases. I'm not trying to save myself from work here. I just want to learn the concept behind doing it right.

That's about it. The rest of the program works fine and dandy. If any of you could help me, please keep the answer easy to understand for a newbie like me so it's easier to grasp the concept :) Thanks!

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
AfroMan
  • 315
  • 1
  • 3
  • 7
  • 1
    Look at using a StringBuilder to build your string and then pass the StringBuilder to the System.out. StringBuilder sb ..... System.out.println(sb.toString()). – ChadNC Oct 30 '12 at 20:28
  • @ChadNC you don't even have to do `sb.toString()`, you can just call `System.out.println(sb)` – Brian Oct 30 '12 at 20:29
  • Basically the same question as [**this**](http://stackoverflow.com/questions/8255077/joining-a-liststring-in-java-with-commas-and-and). – Junuxx Oct 30 '12 at 20:33
  • This is actually a "look-ahead" problem, which is not simple in the general case. It's a good one to puzzle over and consider several solutions -- a good foundation for later work. – Hot Licks Oct 30 '12 at 20:52

3 Answers3

5

Sometimes it's easier to break the problem down a bit. What I'd probably do is create an array of strings: ["2 quarters", "1 dime", "1 nickel", "one cent"]

Then look at how many (valid) array elements I had and loop through N-1 of the N elements, outputting the lines separated by commas. Then (assuming that there's more than one array element) output "and" followed by the last array element.

There are other ways that are "more efficient", but I've been in this biz 40 years, and I'll take "easy to understand and works" over "efficient" any day.

(Of course, this isn't the only way to skin this cat, and probably there are others that are equally simple, but that's for you and others to invent.)

(Note that it's critical to avoid code that must decide, between everyone of your if statements, whether or not to insert "and". When you repeat the same logic over and over again you tend to multiply your errors and create a maintenance nightmare.)

Hot Licks
  • 47,103
  • 17
  • 93
  • 151
  • I was about to mention how I didn't understand anything you just said, but now that I think about it, it makes perfect sense. I'll have to do some more research on arrays, however. I'll definitely consider trying something like this. Thanks for your answer! – AfroMan Oct 30 '12 at 20:34
  • Oh and that awful solution of deciding for "ands" you mentioned was one of the things I was about to resort to, but I stopped myself before I actually bothered. I'd be ashamed to hand something like that in to my teacher xP – AfroMan Oct 30 '12 at 20:38
  • The array thing can be a little tricky until you're used to dealing with arrays. You can either use a java.util.ArrayList, or use a simple String[] array initialized to have (at least) 4 elements, and keep a separate count of how many elements are actually filled in. – Hot Licks Oct 30 '12 at 20:49
  • I would definitely use a `List`. Other than that, this is definitely the most sound advise. – Tim Bender Oct 30 '12 at 20:52
  • +1 for the good practice of using a List and do post-processing over it, even though it looks a bit overkill for 4 elements tops :) – Alexis Pigeon Oct 30 '12 at 21:29
  • Thank you so much! I have finished the program and I must say I couldn't have done it without your help. I can't begin to describe how much I learned during all of this. Thanks again! – AfroMan Nov 02 '12 at 08:23
2

Your current approach is to calculate the count for a coin type and then immediately print the result.

If instead, you first compute the counts for all the coins without any printing, you can then see which is the smallest coin with a nonzero count (and thus the last to be named in the output). Using that, I think you can figure out how to glue the counts together and print the desired text.

Junuxx
  • 14,011
  • 5
  • 41
  • 71
  • My bad. If I included the whole program you'd see I did all the calculations first and what I've shown is merely where I have it print everything! – AfroMan Oct 30 '12 at 20:29
  • @user1786725: Alright, but my suggestion stands. Going from small (cent) to large (quarter), what's the first nonzero count? That is going to be the last term in the output. – Junuxx Oct 30 '12 at 20:31
  • Never thought of it that way... interesting! – AfroMan Oct 30 '12 at 20:39
1

Since you are learning Java, I won't give you the full solution, but here are some directions:

  • store your ouptut in a String variable instead of System.out.printing it bit by bit
  • in that String, remove the trailing comma, if any (only in the cases cents == 0 or nickels > 1, but the latter may be a mistake of yours)
  • replace the last comma by " and", if any
  • output the String

If you are still totally stuck, let us know, I'm sure someone will come up with a ready-made solution (if not already).

Alexis Pigeon
  • 7,423
  • 11
  • 39
  • 44
  • A little more hintage: Use LastIndexOf() =D – Blaise Swanwick Oct 30 '12 at 20:27
  • I'll definitely think about how to apply it. Thanks! – AfroMan Oct 30 '12 at 20:30
  • -1 ... I was going to call this hackish, but it is actually wrong since the answer as written would create bad output when 3 or more coins were in the result. Assuming it is mean to replace the last `,` with `, and` then the answer given won't work for cases with only 2 coins in the result. – Tim Bender Oct 30 '12 at 20:54
  • @TimBender no, I really mean replacing the last `,` with `" and"`, not `", and"`. But now that I think about it, the possible trailing comma should be removed first. Answer edited. – Alexis Pigeon Oct 30 '12 at 21:25