forked from: Levenshtein Distance [live coding test]

by 9re forked from Levenshtein Distance [live coding test] (diff: 1)
♥0 | Line 183 | Modified 2010-02-19 00:42:04 | MIT License
play

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;
	}
}