Code · Interview problems · Problems

Accept-Language Parser

Medium String parsing 2 parts 80 lines View on GitHub ↗

Question

Topic: String parsing · Difficulty: Easy → Medium

An HTTP Accept-Language header lists the languages a client wants, e.g. "en-US, fr-CA, fr-FR". Given the header and the languages the server supports, return the supported ones in the client’s order of preference.

Part 1: exact matches in header order

Trim spaces, match case-insensitively, keep header order, no duplicates.

header    = "   en-US   ,     fr-CA,     fr-FR     "
supported = ["fr-CA", "en-UK", "fr-FR", "en-US"]
→ [en-us, fr-ca, fr-fr]

Part 2: quality weights

Entries can carry a weight: "fr-FR;q=0.8, en-US;q=1" (no q means 1.0). Sort by weight, highest first. Drop q=0 and treat an unparsable q as 0.

Approach: split on , then ;, parse q=, filter to supported languages, stable-sort by weight descending.

LanguageParserPart1.java 29 lines GitHub ↗
/**
 * Problem: Accept-Language Parser
 * Difficulty: Medium
 * Topic: String parsing
 * Question: Return the server-supported languages in the order an Accept-Language header prefers them, then with q= weights. Full statement in README.md.
 */
package dsa.question2;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

public class LanguageParserPart1 {

    public static List<String> parseLanguage(String headers, String[] supportedLanguage) {

        HashSet<String> langauge = new HashSet<>();
        List<String> output = new ArrayList<>();
        String[] headerList = headers.split(",");

        for(int i=0; i<supportedLanguage.length;i++) {
            String lang = supportedLanguage[i].trim().toLowerCase();
            langauge.add(lang);
        }
        for(int i=0;i<headerList.length;i++) {
            String input = headerList[i].trim().toLowerCase();
            if(langauge.contains(input)) {
                langauge.remove(input);
                output.add(input);
            }
        }
        return output;
    }
}
LanguageParserPart2.java 39 lines GitHub ↗
package dsa.question2;

import java.util.*;

public class LanguageParserPart2 {

    public static List<String> parseLanguage(String headers, String[] supportedLanguage) {
        List<String> output = new ArrayList<>();
        if (headers == null) return output;

        Set<String> remaining = new HashSet<>();
        for (String s : supportedLanguage) remaining.add(s.trim().toLowerCase());

        List<Pair> entries = new ArrayList<>();
        for (String token : headers.split(",")) {
            String[] parts = token.split(";");
            String lang = parts[0].trim().toLowerCase();
            double q = 1.0;
            if (parts.length > 1) {
                String param = parts[1].trim();
                if (param.startsWith("q=")) {
                    try {
                        q = Double.parseDouble(param.substring(2).trim());
                    } catch (NumberFormatException e) {
                        q = 0.0;
                    }
                }
            }
            if (q > 0 && remaining.contains(lang)) {
                entries.add(new Pair(lang, q));
            }
        }

        entries.sort((a, b) -> Double.compare(b.q, a.q));

        for (Pair p : entries) {
            if (remaining.remove(p.lang)) output.add(p.lang);
        }
        return output;
    }

    private static class Pair {
        String lang;
        double q;
        Pair(String lang, double q) { this.lang = lang; this.q = q; }
    }
}
Demo.java 12 lines GitHub ↗
package dsa.question2;

import java.util.ArrayList;
import java.util.List;

public class Demo {

  public static void main(String arg[]) {
      // part1
      String header = "   en-US   ,     fr-CA,     fr-FR     ";
      String[] supported_languages =  {"fr-CA", "en-UK", "fr-FR", "en-US"};

      List<String> output = LanguageParserPart1.parseLanguage(header, supported_languages);
      System.out.println(output);
  }

}