0

I have a LinkedList and its elements are books. Books have their prices and a book can be added to the list repeatedly(un-ordered) and each time when they are added their prices may vary. Now I have to find the best selling book in the list by adding up all the different prices of the same book and divide it by the number of occurrence in the list. I am having trouble with the finding all the occurrence of the same book as they are un-ordered.

can anyone give some ideas about this.

thank you.

Dilshad Abduwali
  • 1,388
  • 7
  • 26
  • 47

4 Answers4

2

A little helper class to keep track of total price and number of occurrences will prove invaluable :

public class AverageCounter {

    private int occurrences;

    private BigDecimal totalPrice;

    public BigDecimal currentAverage() {
        return totalPrice.divide(BigDecimal.valueOf(occurrences));
    }

    public void addOccurringPrice(BigDecimal price) {
        occurrences++;
        totalPrice = totalPrice.add(price);
    }
}

Then loop the LinkedList and add entries to a Map<Book, AverageCounter>.

At the end just get the averages from the mapped AverageCounters.

bowmore
  • 10,842
  • 1
  • 35
  • 43
1

Just go through the list and add the books to a Map<String, int> which you can use to keep track of how many times a book is sold.

Check the Map<String, int> to see if the book is already there, if not, add it. If the book is already in the Map<String, int> then increment the int.

user1231232141214124
  • 1,339
  • 3
  • 16
  • 22
  • but every time when the book is added to its book list the price will be different which mean the book is sold based on the customer and specific situation. How do I add up the total price before I divide it by the incremented int in the Map list? – Dilshad Abduwali Sep 01 '13 at 07:20
1

Because i can't comment so I add to previous answer. The simplest way: Just use another map for total. So you have 2 maps: Map Map

Iterate the original linkedlist, count and add price using two maps.

1

Is there aany specific reason you are using a LinkedList?If not a map can make your life a lot easier:

Map<String, List<Book>> bookShelf = new HashMap<String, List<Book>>();

void addBook(Book book) {
    String key = book.name + book.author; // For illustration
    List<Book> bookList = null;
    if (!bookShelf.containsKey(key)) {
        bookList = new ArrayList<Book>();
        bookShelf.put(key, bookList);
    } else {
        bookList = bookShelf.get(key);
    }
    bookList.add(book);
}

double fetchAverage(Book input){
    String key = ""/*key logic*/;
    List<Book> booklist =  bookShelf.get(key);
    double avg = 0.0;
    for(Book b: booklist){
        avg += b.price;
    }
    return avg/booklist.size();
}

OR

in case of LinkedList:

    LinkedList<Book> bookList = new LinkedList<Book>();

    double avg = 0.0;
    int counter = 0;
    for (Book b : bookList) {
        if (b.equals(inputBook)) { // must override hashCode() and equals in
                                    // Book and it should be independent of
                                    // price
            avg += b.price;
            counter++;
        }
    }
    return avg / counter;

You can probably enhance it by keeping the List sorted, so all books with same name and author occure consecutively.

OR Maintain a temporaryList in case you don't want to override equals:

    LinkedList<Book> temporaryBookList = new LinkedList<Book>();

    for (Book b : bookList) {
        if (b.name.equals(inputBook.name) && b.author.equals(inputBook.author)) { 
            temporaryBookList.add(b);
        }
    }

    double avg = 0.0;
    for(Book b : temporaryBookList){
        avg += b.price;
    }
    return avg / temporaryBookList.size();

Note: prices are in double only for illustration. Use of BigDecimal is encouraged for prices and such.

Community
  • 1
  • 1
rocketboy
  • 9,573
  • 2
  • 34
  • 36