Effective sparse translation between whole numbers

I am in the process of developing a specialized regular expression engine that utilizes finite automata. My goal is to manage numerous states, each equipped with its own transition table mapping unicode code points (or UTF-16 code units; I have yet to finalize this decision) to specific state IDs.

There will be scenarios where the tables are exceptionally sparse, while others may be nearly full. Typically, most of the entries will fall within contiguous ranges sharing the same value.

The easiest approach would involve using a lookup table, but this method would consume significant space. Alternatively, a list of (range, value) pairs would occupy less space but might run slower. A binary search tree could provide faster results compared to a list.

Are there more efficient strategies available, possibly making use of existing functionality?

Answer №1

Regrettably, the standard data types in JavaScript, particularly Map, do not offer much support for this specific task due to their lack of relevant methods.

Typically, the majority of entries will belong to consecutive ranges with identical values.

Nevertheless, we can take advantage of this pattern and utilize a binary search approach on sorted arrays, assuming that the transition tables will remain relatively static.

To encode continuous input ranges leading to the same state, store the lowest value of each range in a sorted array. Then, keep the corresponding states at the matching indices in a separate array:

let inputs = [0, 5, 10]; // Input ranges [0,4], [5,9], [10,∞)
let states = [0, 1, 0 ]; // Inputs [0,4] lead to state 0, [5,9] to 1, [10,∞) to 0

When given an input, conduct a binary search on the inputs array similar to Java's floorEntry(k):

// Retrieves the index of the largest element less than or equal to
// the specified element, or returns undefined if none exists:
function floorIndex(sorted, element) {
  let low = 0;
  let high = sorted.length - 1;
  while (low <= high) {
    let mid = low + high >> 1;
    if (sorted[mid] > element) {
      high = mid - 1;
    } else if (sorted[mid] < element) {
      low = mid + 1;
    } else {
      return mid
    }
  }
  return low - 1;
}

// Example: Transition to 1 for emoticons in range 1F600 - 1F64F:
let transitions = {
  inputs: [0x00000, 0x1F600, 0x1F650],
  states: [0,       1,       0      ]
};
let input = 0x1F60B; // 😋
let next = transitions.states[floorIndex(transitions.inputs, input)];

console.log(`transition to ${next}`);

This search operation requires O(log n) steps where n is the count of contiguous input ranges. Consequently, a single state's transition table demands space proportional to O(n). This method remains effective for both sparse and dense transition tables as long as our initial assumption remains valid - the number of successive input ranges resulting in the same state is limited.

Answer №2

It seems like you are dealing with two distinct scenarios ("in many instances, the table will be very sparse, while in other cases it will be almost completely filled").

For the sparse situation, one approach could involve creating a separate sparse index (or multiple layers of indexes), and storing the actual data in a typed array. Since the index(es) would essentially map integers to integers, they could also be represented as typed arrays.

The process of looking up a value might involve the following steps:

  1. Perform a binary search on the index. The index stores pairs as consecutive entries in the typed array – where the first element is the search value, and the second is the position in the dataset (or the next index).
  2. If there are multiple indexes, iterate through step 1 as needed.
  3. Begin iterating through your dataset from the position provided by the last index. As the index is sparse, this position may not be exactly where the value is located, but it serves as a good starting point since the correct value should be close by.
  4. The dataset itself can be represented as a typed array where consecutive pairs contain the key and the corresponding value.

In terms of JavaScript implementation, utilizing typed arrays seems to be a solid choice. They offer speed advantages, especially when paired with indexes. However, if the number of entries is small (a few thousand), skip using indexes and opt for a binary search directly on the typed array (as explained in step 4 above).

As for the dense case, consider options carefully. If repeated values within ranges of keys are common, think about incorporating techniques like run-length encoding – where identical consecutive values are simplified into their frequency followed by the actual value. Once again, leveraging typed arrays along with binary search, and potentially indexes, can enhance efficiency in this scenario.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The type 'number[]' is lacking the properties 0, 1, 2, and 3 found in the type '[number, number, number, number]'

type spacing = [number, number, number, number] interface ISpacingProps { defaultValue?: spacing className?: string disabled?: boolean min?: number max?: number onChange?: (value: number | string) => void } interface IFieldState { value: ...

Kik Card - Using Synchronous XMLHttpRequest within the Kik.js Script

Getting ready to create a mobile web app powered by Kik! First step, insert the Kik.js script at the bottom of your HTML page... <!-- add this script to your webpage --> <script src="http://cdn.kik.com/kik/2.3.6/kik.js"></script> Excel ...

Is the MVC pattern adhered to by ExpressJS?

Currently, I am diving into the world of creating an MVC Website With ExpressJS using resources from I'm curious to know if ExpressJS strictly adheres to the MVC pattern, or if it follows a different approach like Flask which focuses more on the "C" ...

A guide on converting HTML and CSS to a PDF file using JavaScript

I'm facing a challenge where I need to create a custom quote in pdf using data retrieved in JavaScript and sent in HTML. However, the issue is that no library supports CSS for the PDF generation process. After some research, I came across HTML2CANVAS ...

Bring life to the process of adding and removing DOM elements through animation

I am seeking to provide an engaging and interactive experience for my users while ensuring responsiveness. To achieve this goal, I have decided to learn more about web development by creating a card game. My current setup involves clickable elements that ...

Sending the parameter with the URL and receiving the response in return

Can the result be retrieved by calling a URL and sending specific parameters with it? For instance, if I pass two numbers along with the URL, can I receive the sum in return? The addition operation is carried out on the page being called upon. ...

Tips for displaying a React component with ReactDOM Render

_Header (cshtml) <div id="Help"></div> export default class Help { ReactDOM.render( <Help/>, document.getElementById('Help') ); } Help.js (component) } My objective is to di ...

A step-by-step guide on utilizing the v-for index loop to showcase a nested JSON array

My JSON Array has the following structure: items: [ { ID: 11, UserID: "test.com", UserRole: "user", timeStamp: "2021-03-23T15:54:02.125578", dialogs: [ { "Bot" ...

distinguishing the container component from the presentational component within react native

I just started developing apps using React Native and implemented a basic login function with the view and login logic on the same page named HomeScreen.js. However, after reading some articles online, I learned that it's recommended to separate the l ...

Understanding the rationale for rendering Views with vuex dependencies in vueJS

I'm facing an issue with my API call in App.vue that populates the vuex store's state. The Home.vue component displays images based on the store's state, but console errors are thrown before the state is populated. I'm unsure about the ...

Every time I refresh the page, my table is getting filled with blank rows

I created a simple example featuring a form and some PHP/JavaScript code. The JavaScript is used for form validation, while the PHP is utilized to update a MySQL table. function checkForm(){ var x = document.forms['form1']['first'] ...

Interactive JavaScript Slider for Customizing Selection

Recently, I came across a range slider and I am trying to make it more dynamic. The current JavaScript code has hardcoded references to specific HTML elements, and I want to have multiple sliders on my HTML page, each functioning independently. The code sn ...

Issue with binding classes dynamically in vue with svg elements

I'm attempting to create a custom typing program for one of my students using SVG to display the words and class binding with Vue.js. The goal is to change the color of the characters when the correct key is pressed by the user. However, I've enc ...

LinkButton not triggering on Master Page when accessed from Second Child Page in ASP.NET

I am currently working on a project in ASP.NET (Framework 4.0) where I have implemented an Asp LinkButton in the Master Page that is linked to two different pages (Home.aspx and service.aspx). The question at hand is: The LinkButton1 functions properly on ...

Tips for choosing elements that are not next to each other in a JavaScript array

If I have an array and want to select non-consecutive elements, such as the second and fifth elements, is there a simple method to do this? For example: a = ["a","b","c","d","e"] a.select_elements([1,4]) // should yield ["b","e"] EDIT: After some reflec ...

Overlay a small image on top of a larger background image using canvas, then merge them into a single set of pixel

Is there a way to combine a smaller image with a larger background image on one canvas while allowing the smaller image to move around? I'll need to save the original background pixel data so that each frame can be redrawn with the overlay in its upda ...

Steer clear of cross-domain solutions

Currently, I am developing a web application that allows customers to integrate it into their websites by linking to a JavaScript file on my server. Despite the application reading all JavaScript files from my server, I encounter an error when attempting t ...

Having trouble formatting the date value using the XLSX Library in Javascript?

I'm having trouble separating the headers of an Excel sheet. The code I have implemented is only working for text format. Could someone please assist me? const xlsx = require('xlsx'); const workbook = xlsx.readFile('./SMALL.xlsx') ...

Securing child paths in Vue.js

Having trouble protecting child routes from parent routes, facing some issues export default new Router({ routes: [ //frontend routes { {path: 'auth', component: Auth, children: authroutes, beforeEnter: (to, from, n ...

Differences in file loading in Node.js: comparing the use of .load versus command-line

Currently, I am in the process of developing a basic server using vanilla JavaScript and Node.js. For this purpose, I have created a file named database.js, which includes abstractions for database interactions (specifically with redis). One of my objecti ...