klice's blog

stay hungry, stay foolish

公告

统计

2011年12月30日

[数据结构]字符串匹配算法

字符串匹配算法,指在字符串S中,寻找与匹配字符串T相等的子串,如果存在子串,则返回第一个子串的位置,如果不存在子串,则返回-1.

 

普通实现方法

思路:从字符串S的起始位置开始做比较,如果子串和字符串T不相等则向后移动一位,继续比较,直到找到相等的子串,或者已经查找了所有子串。

代码:

View Code
/// <summary>
/// find the index of string T in string S
/// </summary>
/// <param name="S"></param>
/// <param name="T"></param>
/// <returns>if found, return index, else return -1</returns>
public static int GetIndex(string S, string T)
{
int i = 0, j = 0, NotFound = -1, sLen = S.Length, tLen = T.Length;
if (sLen < tLen)
return NotFound;

while (i < sLen && j < tLen)
{
if (S[i] == T[j])
{
i++;
j++;
}
else
{
i = i - j + 1;
j = 0;
}
}
if (j == tLen)
return i - tLen;
else
return NotFound;
}

 

KMP实现方法

思路:从字符串S的起始位置开始做比较,当比较结果为不相等时,假设S的当前位置为i,T的当前位置为j,检查是否存在一个最大值k,满足0<=k<j-1,并且T0Tk与Tj-k-1Tj-1这两个子串相等

如果k不存在,那么同普通实现方法。

如果k存在,此时T0Tk=Tj-k-1Tj-1,而且从之前的比较结果我们可以得知Tj-k-1Tj-1=Si-k-1Si-1,所以可以断定T0Tk=Si-k-1Si-1,所以此时我们不必重新比较T0Tk和Si-k-1Si-1这两个子串,而是比较Si-1和Tk之后的字符是否相等,即i不回退,j回退到k+1,然后继续比较。

现在的问题,转变为如何求这个k,由定义可知,当j=0的时候,k肯定不存在,next[0]=-1,

我们假设next[j]=k,由此可知T0Tk=Tj-k-1Tj-1

如果Tk+1=Tj,那么可推得T0Tk+1=Tj-k-1Tj,即next[j+1]=k+1;

如果Tk+1!=Tj,那么继续比较Tj和Tnext[k+1],如果依然不相等,继续比较Tj和Tnext[next[k+1]],直至Tj与Tn相等,那么next[j+1]=next[n],或者不存在k

代码:

View Code
public static int GetIndexKMP(string S, string T)
{
int i = 0, j = 0, NotFound = -1, sLen = S.Length, tLen = T.Length;
int[] next = GetNextVal(T);
if (sLen < tLen)
return NotFound;
while (i < sLen && j < tLen)
{
if (j == -1 || S[i] == T[j])
{
i++;
j++;
}
else
{
j = next[j];
}
}
if (j == tLen)
return i - tLen;
else
return NotFound;
}

/// <summary>
/// get the next value array of a string T
/// </summary>
/// <param name="T"></param>
/// <returns></returns>
public static int[] GetNextVal(string T)
{
int i = 0, j = -1, tLen = T.Length;
int[] next = new int[tLen];
next[0] = -1;

while (i < tLen - 1)
{
if (j == -1 || T[i] == T[j])
{
i++;
j++;
next[i] = j;
}
else
{
j = next[j];
}
}
return next;
}



posted @ 2011-12-30 23:03 klice 阅读(66) 评论(0) 编辑

2011年7月12日

[ASP.NET] Atlas学习笔记

Atlas是微软提供的一个控件库,用于在ASP.NET中实现ajax效果,全称ASP.NET AJAX Control Toolkit

如何在vs中使用

1. 下载

ASP.NET AJAX Control Toolkit,下载地址

或者可以通过Nuget安装,Tools-->Library Package Manager-->Add Library Package Reference...

 

2.  打开vs,在toolbox中添加控件

在toolbox右键,显示右键菜单,点击“Choose Items...”
   在“Choose Toolbox Items”对话框中,点击“Browse...”按钮,选择刚才下载的dll
 
这样在Toolbox就添加了所有的Atlas控件了,接下来简单介绍下如何使用。

Demo

添加一系列可折叠Panel

1. 添加一个ToolkitScriptManager控件,需要使用Atlas控件,此控件必须添加

2. 添加一个Accordion控件

3. 添加一些列AccordionPanel控件

4. 为Accordion控件添加样式表

 View Code

 
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    
<title></title>
    
<style type="text/css">
        .accordion
        
{
            width
: 400px;
        
}
        
        .accordionHeader
        
{
            border
: 1px solid #2F4F4F;
            color
: white;
            background-color
: #2E4d7B;
            font-family
: Arial, Sans-Serif;
            font-size
: 12px;
            font-weight
: bold;
            padding
: 5px;
            margin-top
: 5px;
            cursor
: pointer;
        
}
        
        .accordionHeaderSelected
        
{
            border
: 1px solid #2F4F4F;
            color
: white;
            background-color
: #5078B3;
            font-family
: Arial, Sans-Serif;
            font-size
: 12px;
            font-weight
: bold;
            padding
: 5px;
            margin-top
: 5px;
            cursor
: pointer;
        
}
        
        .accordionContent
        
{
            background-color
: #D3DEEF;
            border
: 1px dashed #2F4F4F;
            border-top
: none;
            padding
: 5px;
            padding-top
: 10px;
        
}
    
</style>
</head>
<body>
    
<form id="form1" runat="server">
    
<div>
        
<asp:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server">
        
</asp:ToolkitScriptManager>
        
<asp:Accordion ID="Accordion1" CssClass="accordion" HeaderCssClass="accordionHeader"
            HeaderSelectedCssClass
="accordionHeaderSelected" ContentCssClass="accordionContent"
            runat
="server">
            
<Panes>
                
<asp:AccordionPane ID="AccordionPane1" runat="server">
                    
<Header>
                        header1
</Header>
                    
<Content>
                        content1
</Content>
                
</asp:AccordionPane>
                
<asp:AccordionPane ID="AccordionPane2" runat="server">
                    
<Header>
                        header2
</Header>
                    
<Content>
                        content2
</Content>
                
</asp:AccordionPane>
                
<asp:AccordionPane ID="AccordionPane3" runat="server">
                    
<Header>
                        header3
</Header>
                    
<Content>
                        content3
</Content>
                
</asp:AccordionPane>
            
</Panes>
        
</asp:Accordion>
    
</div>
    
</form>
</body>
</html

 

上面的例子里用的都是Atlas控件,同时,Atlas控件也可以应用在ASP.NET标准服务端控件上,例如给一个textbox添加一个colorpicker

1. 在设计页面添加一个textbox,此时应该在textbox边上有一个添加extender的标签,

2. 点击添加一个extender,选择colorpicker

 View Code

 
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        
<asp:ColorPickerExtender ID="TextBox1_ColorPickerExtender" runat="server" 
            Enabled
="True" TargetControlID="TextBox1">
        
</asp:ColorPickerExtender

更多例子

获取源代码

可以通过官方网站上提供的方法获取所有源代码

http://www.asp.net/ajaxlibrary/act_enlist.ashx

自定义Extender

通过查看源代码发现,原来所有的控件都是继承System.Web.UI.ExtenderControl,重写方法GetScriptReferences和GetScriptDescriptors,来实现用javascript操作服务端控件的Dom元素。

GetScriptReferences方法返回IEnumerable<ScriptReference>对象,用于获取脚本资源。

GetScriptDescriptors方法返回IEnumerable<ScriptDescriptor>对象,用于描述脚本,可为客户端脚本添加属性方法等。

这样看来,我们自己也是可以实现自定义的ExtenderControl的,查看了一下MSDN,果然发现了相关的教程

 

看过上面的教程后我也自己尝试开发了一个自定义Extender,TipExtender用于显示Tip

 首先需要新建一个类库项目,添加引用System.Web.Extensions,System.Web

新建一个TipExtender继承ExtenderControl,实现抽象类

 

View Code
[TargetControlType(typeof(Control))]
    
public class TipExtender : ExtenderControl
    {
        
protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors(System.Web.UI.Control targetControl)
        {
            ScriptBehaviorDescriptor descriptor 
= new ScriptBehaviorDescriptor("MyExtender.TipBehavior", targetControl.ClientID);
            
return new List<ScriptDescriptor> { descriptor };
        }

        
protected override IEnumerable<ScriptReference> GetScriptReferences()
        {
            
//microsoft ajax behavior script
            ScriptReference tipBehavior = new ScriptReference("Scripts\\TipBehavior.js");

            
//jquery script
            ScriptReference jQuery = new ScriptReference("Scripts\\jquery-1.4.1.min.js");

            
//my tip script
            ScriptReference tip = new ScriptReference("Scripts\\Tip.js");            

            
return new ScriptReference[] { tipBehavior, jQuery, tip };
        }        
    }

 

 添加脚本文件到Scripts目录下(我这里是用jquery实现的tip,所以需要添加jquery-1.4.1.min.js)

TipBehavior.js

 

View Code
// Register the namespace for the control.
Type.registerNamespace('MyExtender');

MyExtender.TipBehavior 
= function (element) {
    MyExtender.TipBehavior.initializeBase(
this, [element]);
}

MyExtender.TipBehavior.prototype 
= {

    initialize: 
function () {
        MyExtender.TipBehavior.callBaseMethod(
this'initialize');
        

        
var tip = new Tip(this.get_element().id,this.get_element().value);
    },

    dispose: 
function () {
        MyExtender.TipBehavior.callBaseMethod(
this'dispose');
    },    
}

// Register the class as a type that inherits from Sys.UI.Control.
MyExtender.TipBehavior.registerClass('MyExtender.TipBehavior', Sys.UI.Behavior);

if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

 

jquery-1.4.1.min.js

Tip.js

 

View Code
var mousePosition = { x: 100, y: 100 };
$(document).mousemove(
function (e) {
    mousePosition 
= { x: e.pageX, y: e.pageY };
});


var Tip = function (id, text) {
    
var tip = $("#tip");
    
if (tip[0== null) {
        $(
"body").append("<p id='tip'></p>");
        tip 
= $("#tip");
    }

    $(
"#" + id).hover(function () {
        tip.html(
"<p id='tip'>" + text + "</p>");
        tip.css({ display: 
"block", position: "absolute", left: mousePosition.x, top: mousePosition.y });
        tip.fadeOut(
3000);
    },
    
function () {
        tip.hide();
    });
}

 

然后编译成程序集,就可以像Atlas一样添加我自己的ExtenderControl了,需要注意的一点是我没有把脚本嵌入到程序集中,所以在使用的时候要把脚本文件(Scripts)添加到项目中去

 

posted @ 2011-07-12 12:23 klice 阅读(113) 评论(0) 编辑

2011年7月9日

[JQuery]自定义CircleAnimation,Animate方法学习笔记

最近对看了一些JQuery的基础教程,被JQuery深深的吸引住了,以前用过Extjs,看了JQuery不禁感叹,javascript还能这么些,真是太神奇了!

在此贴出一些学习成果,希望能对学习JQuery的其他同学有所帮助,同时也记录下自己的学习情况。

 

看了一些JQuery的官方教程,已经有点心潮澎湃了,就决定自己尝试着写一些东西出来。我看到了很多很绚的动画效果,然后决定自己也尝试一下,我决定要写一个圆周运动的动画效果,下面贴出js代码

 

  1 var CircleAnimation = function (center_left, center_top, id, clockwise, duration) {
  2 return new CircleAnimation.fn.init(center_left, center_top, id, clockwise, duration);
  3 };
  4 
  5 CircleAnimation.fn = CircleAnimation.prototype = {
  6 item: {},
  7  init: 
  8 function (center_left, center_top, id, clockwise, duration) {
  9 this.item = $("#" + id + "");
 10 if (!this.item[0])
 11 return;
 12  currentPoint = {
 13 x: this.item.css("left"== "auto" ? 0 : String(this.item.css("left")).replace("px"""- center_left,
 14 y: this.item.css("top"== "auto" ? 0 : String(this.item.css("top")).replace("px"""- center_top
 15 };
 16 center_left = center_left;
 17 center_top = center_top;
 18 if (currentPoint.x == 0 && currentPoint.y == 0)
 19 return;
 20 = Math.pow(Math.pow(currentPoint.x, 2+ Math.pow(currentPoint.y, 2), 0.5);
 21 
 22 var flag = false;
 23 var caculateMiniAngle = function (angle) {
 24 //caculate the minimum angle diff, if the distance between 2 points less than 1px, we think this 2 ponits angle should be the minimum angle diff
 25 if (Math.sin(angle / 2* 2 * r > 1) {
 26 return caculateMiniAngle(angle / 2);
 27 
 28 else {
 29 return angle;
 30 }
 31 }
 32 
 33  miniAngle = caculateMiniAngle(Math.PI / 4);
 34 
 35 //store data to dom element
 36 this.item.data("currentPoint", currentPoint);
 37 this.item.data("center_left", center_left);
 38 this.item.data("center_top", center_top);
 39 this.item.data("r", r);
 40 this.item.data("clockwise", clockwise);
 41 this.item.data("miniAngle", miniAngle);
 42 this.item.data("duration", duration);
 43 //this.item.data("startX", this.startX);
 44 },
 45 
 46 start: 
 47 function () {
 48 var element;
 49 if (this.id)
 50 element = $("#" + this.id.toString());
 51 else
 52 element = this.item;
 53 
 54 element.animate({ left: 1, top: 1 }, {
 55 duration: element.data(
 56 "duration"),
 57 step: CircleAnimation.fn.caculateNextPoint
 58 });
 59 },
 60 
 61 caculateNextPoint: 
 62 function () {
 63 var el;
 64 el = $(
 65 "#" + this.id.toString());
 66 var sin = el.data("currentPoint").y / el.data("r");
 67 var angle = Math.asin(sin);
 68 if (el.data("currentPoint").x < 0)
 69 angle = Math.PI - angle;
 70 //caculate the angle diff between current point angle and next point angle
 71 var anglediff = el.data("miniAngle");
 72 if (el.data("duration"!= undefined)
 73 anglediff = 2 * Math.PI * 13 / el.data(
 74 "duration");
 75 if (el.data("clockwise"))
 76 angle = angle - anglediff;
 77 else
 78 angle = angle + anglediff;
 79 var y = el.data("r"* Math.sin(angle);
 80 var x = el.data("r"* Math.cos(angle);
 81 var fx = arguments[1];
 82 //set duration big enough then circle animation never stop
 83 fx.options.duration = (
 84 new Date).getTime() - fx.startTime + 10000;
 85 if (fx.prop == "top")
 86 fx.now = y + el.data(
 87 "center_top");
 88 if (fx.prop == "left")
 89 fx.now = x + el.data(
 90 "center_left");
 91 el.data(
 92 "currentPoint", { x: x, y: y });
 93 },
 94 
 95 stop: 
 96 function () {
 97 this.item.queue("fx", []);
 98 this.item.stop();
 99 }
100 };
101 CircleAnimation.fn.init.prototype = CircleAnimation.fn;

(本人第一次写文章,还不知道怎么把demo page内嵌进来,希望知道的同学可以友情提示一下,多谢~)

需要调用只需新建一个CircleAnimation对象,参数分别是圆心位置(center_left, center_top),旋转效果元素id,是否顺时针旋转(clockwise),旋转周期(duratin)。然后调用对象start方法开始动画效果,调用stop方法停止动画效果。js文件下载

 

 

posted @ 2011-07-09 09:43 klice 阅读(967) 评论(7) 编辑