programming
string manipulation
sorting algorithms
coding challenge
algorithm design

Return a new string that sorts between two given strings

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Generating a string that lexicographically sorts between two existing strings is useful in ordered keyspaces, fractional indexing, and collaborative list reordering. The challenge is that simple midpoint math on characters can fail when prefixes overlap or when no finite midpoint exists under your alphabet constraints. A robust algorithm treats strings as variable-length numbers in a chosen base and finds an in-between representation.

Core Sections

Problem framing

Given left < right, find mid such that left < mid < right.

Examples:

  • between "a" and "c" -> "b"
  • between "a" and "ab" -> possible with extended alphabet/length strategy

The second case shows why naive single-char midpoint logic is insufficient.

Simple midpoint approach for fixed alphabet

For many practical cases:

python
1import string
2
3ALPH = string.ascii_lowercase
4IDX = {c: i for i, c in enumerate(ALPH)}
5
6def char_mid(a, b):
7    ia, ib = IDX[a], IDX[b]
8    if ib - ia <= 1:
9        return None
10    return ALPH[(ia + ib) // 2]
11
12print(char_mid('a', 'f'))  # c

This works only when gap > 1 at same position.

Fractional indexing style

When gap is tight, extend length and choose trailing characters.

python
1def between(left, right):
2    # simplified demo, lowercase alphabet only
3    left = left or ""
4    right = right or "{"
5    i = 0
6    while i < len(left) and i < len(right) and left[i] == right[i]:
7        i += 1
8
9    l = left[i] if i < len(left) else 'a'
10    r = right[i] if i < len(right) else '{'
11
12    li = ord(l)
13    ri = ord(r)
14    if ri - li > 1:
15        return left[:i] + chr((li + ri) // 2)
16
17    return left + 'm'

Production systems use stricter, collision-resistant variants.

Choosing alphabet and stability

Define allowed characters up front (for example base62). Higher base reduces string growth frequency.

Handling edge cases

You need policies for:

  • equal inputs,
  • adjacent strings with no immediate gap,
  • maximum key length constraints.

Common Pitfalls

  • Assuming a single-character midpoint always exists.
  • Ignoring prefix edge cases like left="a", right="aa".
  • Changing alphabet rules over time and breaking sort order compatibility.
  • Not defining behavior when left and right are invalid or equal.
  • Using locale-dependent string comparison instead of byte/ordinal lexicographic rules.

Implementation Playbook

To make this topic production-ready, treat implementation as a repeatable workflow instead of a one-time fix. Start by defining an explicit baseline with known inputs, expected outputs, and measured runtime behavior. Baselines are critical because many regressions appear only after dependency upgrades, environment changes, or infrastructure shifts that do not modify application code directly. A baseline lets you detect drift quickly and determine whether a failure came from logic changes, runtime configuration, or platform behavior.

Next, design a small but representative validation matrix that covers happy-path, edge-case, and failure-path scenarios. Keep the matrix lightweight enough to run frequently, ideally in local development and CI, and strict enough to catch common integration mistakes. If this topic depends on external services, include deterministic stubs or contract fixtures so tests remain stable and actionable. For observability, log key identifiers, decision branches, and outcome statuses in a structured format; this allows fast correlation in dashboards and incident timelines without manual guesswork.

After correctness checks, add operational safeguards. Define timeout behavior, retry policy, and rollback triggers before rollout. Avoid making multiple high-risk changes simultaneously; apply one change, verify, then continue. Incremental rollout minimizes blast radius and produces clearer diagnostics when behavior diverges from expectations. In shared systems, publish a short runbook that lists prerequisites, expected metrics, and first-response troubleshooting steps. This documentation prevents repeated rediscovery work and improves handoff quality across teams.

Use the following execution checklist for consistent delivery:

text
11. Capture baseline behavior and expected outputs
22. Run happy-path, edge-case, and failure-path tests
33. Validate environment and dependency compatibility
44. Record structured logs and key performance metrics
55. Roll out incrementally with clear rollback criteria
66. Update runbook notes with observed outcomes

Summary

To create a string between two strings reliably, treat the problem as ordered key generation, not simple character averaging. Use a consistent alphabet, handle prefix and adjacency edge cases, and define deterministic fallback rules when no short midpoint exists.


Course illustration
Course illustration

All Rights Reserved.