forked from: Levenshtein Distance [live coding test]
forked from Levenshtein Distance [live coding test] (diff: 1)
ActionScript3 source code
/**
* Copyright 9re ( http://wonderfl.net/user/9re )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/pj7R
*/
// forked from 9re's Levenshtein Distance [live coding test]
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.Event;
import flash.utils.getTimer;
public class LevenshteinDistanceTest extends Sprite {
private var _textField:TextField = new TextField;
private static var _trace:Function = trace;
private var _executer:Sprite = new Sprite;
private const INTERVAL:int = 5;
private var _log:Array;
private var _grid:Grid;
private var _count:int = 0;
public function LevenshteinDistanceTest() {
addChild(this._textField);
this._textField.width = 465;
this._textField.height = 465;
test();
}
private function test():void {
var i:int = 0;
var j:int = 0;
//trace(calcDistance('string', 'string')); // 0
calcDistance('string', 'structure'); // 3
//trace(calcDistance('string', 'string compare')); // 6
_executer.addEventListener(Event.ENTER_FRAME, execute);
}
private function execute(e:Event):void {
if (_log && _log.length) {
var t:int = getTimer();
var log:*;
if (_count++ % INTERVAL == 0) {
log = _log.shift();
if (log)
_grid.setData(log.index, log.value);
}
_count %= INTERVAL;
}
}
private function trace(...o:Array):void {
this._textField.appendText(o + '\n');
_trace(o);
}
// calculates the Levenshtein distance of
// str0 & str1
public function calcDistance(str0:String, str1:String):int {
// data table
// use array for practical use
//var table:Array = [];
var table:DataWithLogger = new DataWithLogger;
var len0:int = str0.length;
var len1:int = str1.length;
var u:int = len0 + 1;
// table is 2 dimensional array
// but simply implement this as
// 1-dimensional array for now
// main purpose for this is to
// log data without changing
// syntax for accessing data
var i:int, j:int;
for (i = 0; i <= len0; ++i)
table[i] = i;
for (j = 0; j <= len1; ++j)
table[j * u] = j; // set j for (col, row) = (0, j)
var cost:int; // cost for deleting, inserting or replacing
for (j = 1; j <= len1; ++j) {
for (i = 1; i <= len0; ++i) {
// if two chars are same cost equals to zero
cost = (str0.charAt(i - 1) == str1.charAt(j - 1)) ? 0 : 1;//
table[i + u * j] = Math.min(
table[i - 1 + u * j] + 1,
table[i + u * (j - 1)] + 1,
table[i - 1 + u * (j - 1)] + cost
);
}
}
_log = table.log;
_grid = new Grid(len0 + 1, len1 + 1);
_grid.x = (465 - _grid.width) / 2;
_grid.y = (465 - _grid.height) / 2;
_grid.columnLabel = str0;
_grid.rowLabel = str1;
addChild(_grid);
return table.pop();
}
}
}
import flash.display.Sprite;
import flash.text.*;
class Grid extends Sprite {
private const H:int = 18;
private const W:int = 20;
private var _tfs:Array;
private var _column:int;
private var _row:int;
private var _tfm:TextFormat = new TextFormat('_typewriter', 18, 0);
public function Grid(column:int, row:int) {
_column = column;
_row = row;
var i:int = 0;
var tfm:TextFormat = _tfm;
var tf:TextField;
_tfs = [];
while (i < _column * _row) {
addChild(tf = new TextField);
tf.defaultTextFormat = _tfm;
tf.text = '0';
tf.x = (i % _column) * W;
tf.y = Math.floor(i / _column) * H;
_tfs.push(tf);
i++;
}
}
public function set columnLabel(value:String):void {
var tf:TextField;
var label:TextField;
for (var i:int = 0; i < _column; ++i) {
tf = _tfs[i + 1];
label = new TextField;
label.defaultTextFormat = _tfm;
label.x = tf.x;
label.y = tf.y - H;
label.text = value.charAt(i);
this.adjustTextFieldSize(label);
addChild(label);
}
}
public function set rowLabel(value:String):void {
var tf:TextField;
var label:TextField;
for (var i:int = 0; i < _row; ++i) {
tf = _tfs[(i+1) * _column];
if (tf == null) return;
label = new TextField;
label.defaultTextFormat = _tfm;
label.x = tf.x - W;
label.y = tf.y;
label.text = value.charAt(i);
this.adjustTextFieldSize(label);
addChild(label);
}
}
public function get column():int {
return _column;
}
public function get row():int {
return _row;
}
public function setData(index:int, value:int):void {
var column:int = index % _column;
var row:int = Math.floor(index / _column);
var tf:TextField = _tfs[column + row * _column];
tf.text = value + '';
this.adjustTextFieldSize(tf);
}
private function adjustTextFieldSize(tf:TextField):void {
// auto size
tf.width = tf.textWidth + 4;
tf.height = tf.textHeight + 4;
}
}
import flash.utils.Proxy;
import flash.utils.flash_proxy;
class DataWithLogger extends Proxy {
private var _data:Array;
private var _log:Array;
public function DataWithLogger () {
_data = [];
_log = [];
_data["log"] = _log;
}
flash_proxy override function callProperty(name:*, ...rest:Array):* {
try {
var method:*// trying to find method
method = _data[name];
if (method && typeof method == 'function') {
method.apply(null, rest);
}
} catch (e:Error) {
}
}
public function get log():Array {
return _log.slice();
}
public function pop():* {
return _data.pop();
}
flash_proxy override function getProperty(name:*):* {
return _data[name];
}
flash_proxy override function setProperty(name:*, value:*):void {
_log.push({
index: name,
value: value
});
_data[name] = value;
}
}