Hone logo
Hone
Problems

String Interning in JavaScript

String interning is an optimization technique where identical string literals are stored only once in memory. This reduces memory usage and can improve performance, especially when dealing with a large number of repeated strings. Your task is to implement a basic string interning mechanism in JavaScript.

Problem Description

You need to create a JavaScript class called StringInterner. This class should maintain a registry of interned strings. When a string is passed to the intern() method, the class should check if the string already exists in the registry. If it does, the method should return the existing interned string. If not, the string should be added to the registry, and the method should return the newly interned string. The returned string should behave exactly like a regular JavaScript string – it should support all standard string methods and operations.

Key Requirements:

  • intern(str) method: Takes a string str as input and returns an interned string.
  • Registry: Maintain a private registry (e.g., a JavaScript object) to store interned strings.
  • Equality Check: Use strict equality (===) to compare strings for interning.
  • Immutability: The interned strings should be immutable. Modifying an interned string should not affect the original string in the registry or other references to it.
  • String Methods: The returned interned string should support all standard JavaScript string methods (e.g., substring, toUpperCase, indexOf).

Expected Behavior:

The StringInterner should efficiently reuse identical strings, minimizing memory consumption. Multiple calls to intern() with the same string should always return the same interned string object.

Edge Cases to Consider:

  • Empty strings.
  • Strings with leading/trailing whitespace.
  • Strings containing special characters.
  • Large strings.
  • Strings that are already interned (e.g., string literals).

Examples

Example 1:

Input:
const interner = new StringInterner();
interner.intern("hello");
interner.intern("world");
interner.intern("hello");

Output:
[ 'hello', 'world', 'hello' ]  (where the last 'hello' is the same object as the first)

Explanation:
The first "hello" is interned and stored. The second "world" is interned and stored. The third "hello" finds an existing interned string and returns it.

Example 2:

Input:
const interner = new StringInterner();
const str1 = interner.intern("  hello  ");
const str2 = interner.intern("hello");
const str3 = interner.intern("  hello  ");

Output:
[ '  hello  ', 'hello', '  hello  ' ] (str1 and str3 are the same object)

Explanation:
"  hello  " and "hello" are different strings due to the whitespace.  The first "  hello  " is interned. The second "hello" is interned. The third "  hello  " finds the first interned string and returns it.

Example 3: (Edge Case - Already Interned)

Input:
const interner = new StringInterner();
const str1 = interner.intern("test");
const str2 = "test";

Output:
[ 'test', 'test' ] (str1 and str2 are the same object)

Explanation:
The string "test" is interned.  A new string literal "test" is created, but the interner returns the already interned string.

Constraints

  • The StringInterner class should be implemented in JavaScript.
  • The registry should be implemented using a JavaScript object.
  • The intern() method should have a time complexity of O(1) on average for lookups and insertions.
  • The interned strings should be immutable.
  • The returned interned strings should support all standard JavaScript string methods.
  • The maximum length of a string to be interned is 1000 characters.

Notes

  • Consider using a Map instead of a plain JavaScript object for the registry if you want to ensure that keys are always strings. However, a plain object is acceptable for this challenge.
  • Focus on the core functionality of string interning – efficient storage and retrieval of identical strings. You don't need to worry about advanced features like garbage collection or automatic de-interning.
  • Think about how to ensure that the interned strings are truly immutable. Creating a new string object each time a method is called is one approach, but it can be inefficient. Consider returning a proxy object that intercepts string method calls and returns the result of applying the method to the original interned string.
Loading editor...
javascript