Search code examples
javasearcharraylisthashmapbufferedreader

How to reduce runtime of HashMap searching?


I am asked to make this program. Below here is the sample program flow.

// first input: how many data you want to input. Data is consisted of name and phone number. Both are string.
3 

// here is the data-entry procedure. I use HashMap. 3 iteration to input the names and phone numbers
hans
12345678
dion
123456789
harry
12345671

// after the data is entered, I entered (also 3, taken from the entry at first input) 3 names to be searched within the HashMap. This can be any name that you can think of. As long as the name are in the HashMap, the program will display the person's name and his/her phone num.
herry
hans
harry

//result will be written as 'not found' if the key (name) is not present in HashMap. This is the sample output
not found
hans=12345679
harry=12345671

This is the limitation for the program.
Program limitation

Actually, my program is already run successfully. This is the code I'm using and the screenshot of the output is attached below.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class HM2a {

    static List<String> listQuery = new ArrayList<String>();

    public static void loop(String name, HashMap<String, String> phonebook) {
        String key, value;
        String result = "";
        for (Map.Entry<String, String> entry : phonebook.entrySet()) {
            key = entry.getKey();
            value = entry.getValue();
            if (name.equals(key)) {
                result = key + "=" + value;
                listQuery.add(result);
                return;
            }
        }
        result = "Not found";
        listQuery.add(result);
    }

    public static void main(String[] args) throws IOException {
        HashMap<String, String> phonebook = new HashMap<String, String>();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));

        try {
            int entries = Integer.parseInt(bufferedReader.readLine());
            String query = "";
            String list = "";

            for (int i = 0; i < entries; i++) {
                String name = bufferedReader.readLine();
                String phonenum = bufferedReader.readLine();
                name = name.toLowerCase();
                phonebook.put(name, phonenum);
            }

            for (int i = 0; i < entries; i++) {
                query = bufferedReader.readLine();
                query = query.toLowerCase();
                loop(query, phonebook);
            }

            for (int i = 0; i < listQuery.size(); i++) {
                System.out.println(listQuery.get(i));
            }
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

Output, run by NetBeans:
enter image description here

The problem is, my code is graded by a local autograder (silimar like the HackerRank one) used by my campus, and it keeps saying (from the test case) that my runtime always exceeds 5s for 3 cases. And unfortunately, I can't ask what the test cases are.
Is there any way to make my code more efficient, especially the search algorithm, to reduce the runtime? I've honestly run out of ideas. At first I use scanner, but then I learned that scanner uses a lot of memory and I changed it to BufferedReader. It wirked, but now I am facing runtime problem.

This is the result shown by the autograder.
enter image description here


Solution

  • As suggested at comments above, I modify this part of searching using get. This is the modification. I also delete the loop method.

                for (int i = 0; i < entries; i++) {
                    query = bufferedReader.readLine();
                    query = query.toLowerCase();
                    if (phonebook.get(query) == null) {
                        String result = "Not found";
                        listQuery.add(result);
                    } else {
                        String result = query + "=" + phonebook.get(query);
                        listQuery.add(result);
                    }
                }
    

    This is the final result. It has been graded as perfect score Result from autograder