Fixed-Width Record Parser

medium Files and I/O

Problem

Each input line is a record with fixed columns: columns 1 to 10 hold the name (padded with spaces on the right), columns 11 to 13 hold the age (padded with spaces on the left), and the rest of the line is the city (it may contain spaces). For every line print name|age|city, without the padding spaces, and the age as a plain number.

Constraints

  • 1 <= lines <= 100
  • every line has at least 14 characters

Examples

Input

Amit       25Pune

Output

Amit|25|Pune

Solutions

Best approachTime O(total length)Space O(total length)

A fixed-width format has no separators. The position of a character tells which field it belongs to, so we cut the line at column numbers and remove the padding with trim.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Parse the records.
 * Input   : Record lines.
 * Output  : name|age|city lines.
 * Approach: Cut by position
 * Time    : O(total length)
 * Space   : O(total length)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
    // This method solves the task. It receives the input and returns the answer.
    static String[] solve(String[] lines) {
        java.util.List<String> out = new java.util.ArrayList<String>();
        for (String line : lines) {
            if (line.trim().isEmpty()) {
                continue;
            }
            // Step 1: The columns are at fixed places, so substring cuts them out. The end index is not included.
            String name = line.substring(0, 10).trim();
            int age = Integer.parseInt(line.substring(10, 13).trim());
            // Step 2: Everything after column 13 is the city.
            String city = line.substring(13).trim();
            out.add(name + "|" + age + "|" + city);
        }
        return out.toArray(new String[0]);
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        java.util.List<String> all = new java.util.ArrayList<>();
        while (scanner.hasNextLine()) {
            all.add(scanner.nextLine());
        }
        String[] lines = all.toArray(new String[0]);
        System.out.println(String.join("\n", solve(lines)));
    }
}
Hints (2)
  1. Why is the end index of substring not included?
  2. What does trim remove?