晚上看到有算法分享关于怎么在10万个手机号码中选择重复号码的问题。

刚好晚上有空,也写了一个算法。

 

View Code
Dictionary<intint> dic = new Dictionary<intint>();
            
int count3 = 0;
            
            
foreach (var item in mobileArray)
            {
                var hashCode 
= item.GetHashCode();
                
int outInt = 0;

                
if (dic.TryGetValue(hashCode, out outInt))
                {
                    
if (outInt == 1)
                    {
                        count3
++;
                        dic[hashCode] 
= 2;
                    }
                }
                
else
                    dic[hashCode] 
= 1;

            }

 

有下面几点需要注意:

  1. Dictionary的Key本身是hash,效率很高
  2. 相同的字符串在.net实际上是同一个地址,所以GetHashCode是一样的。

效果:

欢迎各位高手弄出个更快的算法

 

所有代码

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 手机号码重复算法
{
    
unsafe class Program
    {
        
static void Main(string[] args)
        {
            
//示例数组,存放手机号
            string[] mobileArray = new string[100000];// { "13900001234", "13900001235", "13900001236", "13900001237", "13900001234" };

            
for (int i = 0; i < 100000; i++)
            {
                mobileArray[i] 
= "1390000"
                    
+ (i.ToString().Length > 4 ? i.ToString().Substring(04) : (i.ToString() + "0000").Substring(04));
            }

            
////linq语句来实现【select mobile from tmpTable group by mobile having count(*)>1】的效果
            var selMobile = from n in mobileArray group n by n into g where g.Count() > 1 select g.Distinct();// select g;



            System.Diagnostics.Stopwatch sw 
= new System.Diagnostics.Stopwatch();
            sw.Reset();
            sw.Start();
            
int count1 = 0;
            
//通过两层循环输出重复的手机号
            foreach (var mobile in selMobile)
            {
                
foreach (string multiMobile in mobile)
                {
                    count1
++;
                    
//Console.WriteLine(multiMobile);
                }
            }

            sw.Stop();

            Console.WriteLine(
"Linq共有重复号" + count1 + "耗时" + sw.ElapsedMilliseconds);

            TenNodeTree tree 
= new TenNodeTree();
            TenNodeTree tree2 
= new TenNodeTree();

            sw.Reset();
            sw.Start();
            
int count2 = 0;
            
//mobileArray = new string[] { "13900001234", "13900001235", "13900001236", "13900001237", "13900001234", "13900001236" };

            
foreach (var item in mobileArray)
            {
                
fixed (char* no = item)
                {
                    
if (!tree.Add(no, 11))
                    {
                        
if (tree2.Add(no, 11))
                        {
                            count2
++;
                        }
                    }
                }

            }

            sw.Stop();

            Console.WriteLine(
"十叉树共有重复号" + count1 + "耗时" + sw.ElapsedMilliseconds);



            sw.Restart();
            Dictionary
<intint> dic = new Dictionary<intint>();
            
int count3 = 0;
            
            
foreach (var item in mobileArray)
            {
                var hashCode 
= item.GetHashCode();
                
int outInt = 0;

                
if (dic.TryGetValue(hashCode, out outInt))
                {
                    
if (outInt == 1)
                    {
                        count3
++;
                        dic[hashCode] 
= 2;
                    }
                }
                
else
                    dic[hashCode] 
= 1;

            }

           

            sw.Stop();
            Console.WriteLine(
"hash计算共有重复号" + count3 + "耗时" + sw.ElapsedMilliseconds);

            Console.ReadLine();

        }

        
class TenNodeTree
        {
            
public TenNode Root = new TenNode();

            
public bool Add(char* no, int len)
            {
                TenNode cnode 
= Root;
                
bool isadd = false;

                
for (int i = 0; i < len; i++)
                {
                    
char k = *no;

                    
if (cnode.Child[k - 48== null)
                    {
                        isadd 
= true;
                        cnode.Child[k 
- 48= new TenNode();
                    }
                    cnode 
= cnode.Child[k - 48];

                    no
++;

                }

                
return isadd;

            }

        }

        
class TenNode
        {
            
public TenNode[] Child = new TenNode[10];
        }


    }
}

 

 

posted @ 2011-07-21 22:32 星际迷茫 阅读(141) 评论(4) 编辑
  1. 正则表达式的开发一定要使用工具(除非特别简单的),推荐RegExBuilder.
  2. 最难以理解的是零宽断言和组,其中捕获组说明如下

  (?'group') 把捕获的内容命名为group,并压入堆栈(Stack)

  (?'-group') 从堆栈上弹出最后压入堆栈的名为group的捕获内容,如果堆栈本来为空,则本分组的匹配失败

  (?(group)yes|no) 如果堆栈上存在以名为group的捕获内容的话,继续匹配yes部分的表达式,否则继续匹配no部分

  (?!) 零宽负向先行断言,由于没有后缀表达式,试图匹配总是失败

 3.   正则表达式的本身,是(位置+长度)的匹配,而且匹配的部分,要满足正则表达式位置的连续。而零宽断言中的

(?=exp)

匹配exp前面的位置

(?<=exp) 匹配exp后面的位置

 都是匹配位置。

 4.经过艰苦的思考,发现(?<=exp)的exp部分是从右向左匹配字符串的。

比如,下面的正则表达式,因为(?(t)(?'f'')|(?'x'"))* 先执行,会给x的组加上匹配,这样会导致(?(x)()|()),只会执行红色的部分。

 (?<=^[^'"]*
(?(x)()|())
[^'"]*
(?(t)(?'f'')|(?'x'"))*
[^'"]*
)
1

    5.  <的都应该出现在前面,比如

(?<!exp) 匹配前面不是exp的位置

(?<=exp) 匹配exp后面的位置

 

posted @ 2010-05-17 13:07 星际迷茫 阅读(53) 评论(0) 编辑

最近一个进项目组时间不长的员工完成一个较为复杂的js代码给我查看,我看了以后,提出了些待改进的问题就走了。刚走了没有多久,听到这个员工小声对旁边的人说:X 哥都不表扬我。

成功学大师卡耐基的著作“人性的弱点”前几章重点讲述了赞美的意义,(第一章,做个批评的吝啬鬼,第二章,给别人留足面子,第三章,用赞美来激励他人,第四章不要对别人的优点视而不见)。他在文章里说:“我们都希望得到认可和赏识,而且会尽一切努力去得到它。”“一个重要的原则是,称赞最微小的进步并称赞其每一次进步。”现在,我能真切地体会到赞美的重要性。我们都能记住小时候,老师对自己的某次表扬,某次考试或者表现在班级里出类拔萃。。如果你还对赞美有怀疑的话,我想列举下面几个事实:

  • 为什么玩家对网游上瘾?因为游戏中的每一次战斗获得的东西和经验,每一次升级的能力提高都让玩家有莫大的满足感。这会让你去做一些自己都不知道为什么要做的事情,只为了让自己愉悦和满足,去获得其他玩家的尊重。现实社会对你努力的漠然导致只有游戏才能最好激励你继续付出,每一次的付出,每一次的金币和经验的积累。一些貌似毫无意义的虚拟经验和财富驱动着无数玩家在废寝忘食中如痴如醉。
  • 玫琳凯是美国历史上最伟大的女性企业家,在玫琳凯早期职业生涯中,一些不愉快的经验教给她很多待人之道。一次她参加了一整天销售讲习,有位销售经理做了一场激励士气的演讲,玫琳凯很渴望和他握手。“我在队伍中排了3个小时,好不容易轮到我和他见面,但他从未正眼瞧过我一眼,只是从我肩膀上望过去,看看队伍还有多长,他甚至没有察觉到我正在和他握手。虽然我明白他很累,但我也是一样——在队伍中等待了3个小时,我的疲惫并不亚于他!我觉得受到了伤害和侮辱,因为他根本没有把我看在眼里。从那时起,我便下定决心,如果有一天人们排队来和我握手,我将给每一位来到我面前的人全然的关注,不管我自己是多么疲劳!”在玫琳凯公司成为一家大公司后,玫琳凯曾多次站在长长的队伍前,和上百位人士握手长达数小时。一旦她感到累了,她总是想起自己从前排队和那位销售经理握手的情形,并立即打起精神,直视握手者的眼睛,尽可能地说些比较亲切的话。也许只是几句简短的闲谈,如“我喜欢你的发型”或是“你的衣裳漂亮极了”,但她尽可能给予对方全然的注意,而且决不允许其他事情打扰自己。“在握手的同时,我都将对方视为最重要的人。”
  • 比尔盖茨在1975年母亲节时给母亲寄了一张卡片,他用斜体英文写了这么一段:我爱您!,妈妈,您从来不说我比别的孩子差,您总是从我在干得事情当中,不断寻找值得赞许的地方。我怀念和您一起的所有时光。

 下次我一定会找个机会对这个同事说:你这次写的代码非常出色,完全实现了想要的效果,我在你这个年龄的时候远达不到这个能力。当然这里面对日后的重用性没有考虑,程序写的比较固定。我相信以后能看到你在这方面有更大的进步。

posted @ 2010-02-09 20:09 星际迷茫 阅读(2609) 评论(22) 编辑
1.         document.write( " "); 输出语句
2.JS中的注释为//
3.传统的HTML文档顺序是:document- >html- >(head,body)
4.一个浏览器窗口中的DOM顺序是:window- >(navigator,screen,history,location,document)
5.得到表单中元素的名称和值:document.getElementById( "表单中元素的ID號 ").name(或value)
6.一个小写转大写的JS: document.getElementById( "output ").value = document.getElementById( "input ").value.toUpperCase();
7.JS中的值类型:String,Number,Boolean,Null,Object,Function
8.JS中的字符型转换成数值型:parseInt(),parseFloat()
9.JS中的数字转换成字符型:( " " 变量)
10.JS中的取字符串长度是:(length)
11.JS中的字符与字符相连接使用號.
12.JS中的比较操作符有:==等于,!=不等于, >, >=, <. <=
13.JS中声明变量使用:var来进行声明
14.JS中的判定语句结构:if(condition){}else{}
15.JS中的循环结构:for([initial expression];[condition];[upadte expression]) {inside loop}
16.循环中止的命令是:break
17.JS中的函数定义:function functionName([parameter],...){statement[s]}
18.当文件中出现多个form表单时.可以用document.forms[0],document.forms[1]来代替.
19.窗口:打开窗口window.open(), 关闭一个窗口:window.close(), 窗口本身:self
20.状態栏的设置:window.status= "字符 ";
21.弹出提示信息:window.alert( "字符 ");
22.弹出確认框:window.confirm();
23.弹出输入提示框:window.prompt();
24.指定当前显示链接的位置:window.location.href= "URL "
25.取出窗体中的所有表单的数量:document.forms.length
26.关闭文档的输出流:document.close();
27.字符串追加连接符: =
28.创建一个文档元素:document.createElement(),document.createTextNode()
29.得到元素的方法:document.getElementById()
30.设置表单中所有文本型的成员的值为空:
var form = window.document.forms[0]
for (var i = 0; i <form.elements.length;i ){
if (form.elements.type == "text "){
form.elements.value = " ";
}
}
31.复选按钮在JS中判定是否选中:document.forms[0].checkThis.checked (checked属性代表为是否选中返回TRUE或FALSE)
32.单选按钮组(单选按钮的名称必须相同):取单选按钮组的长度document.forms[0].groupName.length
33.单选按钮组判定是否被选中也是用checked.
34.下拉列表框的值:document.forms[0].selectName.options[n].value (n有时用下拉列表框名称加上.selectedIndex来確定被选中的值)
35.字符串的定义:var myString = new String( "This is lightsword ");
36.字符串转成大写:string.toUpperCase(); 字符串转成小写:string.toLowerCase();
37.返回字符串2在字符串1中出现的位置:String1.indexOf( "String2 ")!=-1则说明没找到.
38.取字符串中指定位置的一个字符:StringA.charAt(9);
39.取出字符串中指定起点和终点的子字符串:stringA.substring(2,6);
40.数学函数:Math.PI(返回圆周率),Math.SQRT2(返回开方),Math.max(value1,value2)返回两个数中的最在值,Math.pow(value1,10)返回

value1的十次方,Math.round(value1)四舍五入函数,Math.floor(Math.random()*(n 1))返回隨机数
41.定义日期型变量:var today = new Date();
42.日期函数列表:dateObj.getTime()得到时间,dateObj.getYear()得到年份,dateObj.getFullYear()得到四位的年份,dateObj.getMonth()得

到月份,dateObj.getDate()得到日,dateObj.getDay()得到日期几,dateObj.getHours()得到小时,dateObj.getMinutes()得到

分,dateObj.getSeconds()得到秒,dateObj.setTime(value)设置时间,dateObj.setYear(val)设置年,dateObj.setMonth(val)设置

月,dateObj.setDate(val)设置日,dateObj.setDay(val)设置星期几,dateObj.setHours设置小时,dateObj.setMinutes(val)设置

分,dateObj.setSeconds(val)设置秒 [注重:此日期时间从0开始计]
43.FRAME的表示方式: [window.]frames[n].ObjFuncVarName,frames[ "frameName "].ObjFuncVarName,frameName.ObjFuncVarName
44.parent代表父亲对象,top代表最顶端对象
45.打开子窗口的父窗口为:opener
46.表示当前所属的位置:this
47.当在超链接中调用JS函数时用:(javascript :)来开头后面加函数名
48.在老的浏览器中不执行此JS: <!-- //-- >
49.引用一个文件式的JS: <script type= "text/javascript " src= "aaa.js " > </script >
50.指定在不支持脚本的浏览器显示的HTML: <noscript > </noscript >
51.当超链和onCLICK事件都有时,则老版本的浏览器转向a.html,否则转向b.html.例: <a href= "a.html " >dfsadf </a >
52.JS的內建对象

有:Array,Boolean,Date,Error,EvalError,Function,Math,Number,Object,RangeError,ReferenceError,RegExp,String,SyntaxError,TypeErr

or,URIError
53.JS中的换行:\n
54.窗口全屏大小: <script >function fullScreen(){ this.moveTo

(0,0);this.outerWidth=screen.availWidth;this.outerHeight=screen.availHeight;}window.maximize=fullScreen; </script >
55.JS中的all代表其下层的全部元素
56.JS中的焦点顺序:document.getElementByid( "表单元素 ").tabIndex = 1
57.innerHTML的值是表单元素的值:如 <p id= "para " > "how are <em >you </em > " </p >,则innerHTML的值就是:how are <em >you </em >

2.       58.innerTEXT的值和上面的一样,只不过不会把 <em >这种標记显示出来.
59.contentEditable可设置元素是否可被修改,isContentEditable返回是否可修改的状態.
60.isDisabled判定是否为禁止状態.disabled设置禁止状態
61.length取得长度,返回整型数值
62.addBehavior()是一种JS调用的外部函数文件其扩展名为.htc
63.window.focus()使当前的窗口在所有窗口之前.
64.blur()指失去焦点.与FOCUS()相反.
65.select()指元素为选中状態.
66.防止用户对文本框中输入文本:
67.取出该元素在页面中出现的数量:document.all.tags( "div(或其它HTML標记符) ").length
68.JS中分为两种窗体输出:模態和非模態.window.showModaldialog(),window.showModeless()
69.状態栏文字的设置:window.status= &apos;文字 &apos;,默认的状態栏文字设置:window.defaultStatus = &apos;文字. &apos;;
70.添加到收藏夹:external.AddFavorite( "http://www.dannyg.com ";, "jaskdlf ");
71.JS中碰到脚本错误时不做任何操作:window.onerror = doNothing; 指定错误句柄的语法为:window.onerror = handleError;
72.JS中指定当前打开窗口的父窗口:window.opener,支持opener.opener...的多重继续.
73.JS中的self指的是当前的窗口
74.JS中状態栏显示內容:window.status= "內容 "
75.JS中的top指的是框架集中最顶层的框架
76.JS中关闭当前的窗口:window.close();
77.JS中提出是否確认的框:if(confirm( "Are you sure? ")){alert( "ok ");}else{alert( "Not Ok ");}
78.JS中的窗口重定向:window.navigate( "http://www.sina.com.cn ";);
79.JS中的打印:window.print()
80.JS中的提示输入框:window.prompt( "message ", "defaultReply ");
81.JS中的窗口滚动条:window.scroll(x,y)
82.JS中的窗口滚动到位置:window.scrollby
83.JS中设置时间间隔:setInterval( "expr ",msecDelay)或setInterval(funcRef,msecDelay)或setTimeout
84.JS中的模態显示在IE4 行,在NN中不行:showModalDialog( "URL "[,arguments][,features]);
85.JS中的退出之前使用的句柄:function verifyClose(){event.returnValue= "we really like you and hope you will stay longer. ";}}

window.=verifyClose;
86.当窗体第一次调用时使用的文件句柄:onload()
87.当窗体关闭时调用的文件句柄:onunload()
88.window.location的属性: protocol(http:),hostname(http://www.example.com/),port(80),host(http://www.example.com/),pathname

( "/a/a.html "),hash( "#giantGizmo ",指跳转到相应的锚记),href(全部的信息)
89.window.location.reload()刷新当前页面.
90.window.history.back()返回上一页,window.history.forward()返回下一页,window.history.go(返回第几页,也可以使用访问过的URL)
91.document.write()不换行的输出,document.writeln()换行输出
92.document.body.noWrap=true;防止链接文字折行.
93.变量名.charAt(第几位),取该变量的第几位的字符.
94. "abc ".charCodeAt(第几个),返回第几个字符的ASCii码值.
95.字符串连接:string.concat(string2),或用 =进行连接
96.变量.indexOf( "字符 ",起始位置),返回第一个出现的位置(从0开始计算)
97.string.lastIndexOf(searchString[,startIndex])最后一次出现的位置.
98.string.match(regExpression),判定字符是否匹配.
99.string.replace(regExpression,replaceString)替换现有字符串.
100.string.split(分隔符)返回一个数组存储值.
101.string.substr(start[,length])取从第几位到指定长度的字符串.
102.string.toLowerCase()使字符串全部变为小写.
103.string.toUpperCase()使全部字符变为大写.
104.parseInt(string[,radix(代表进制)])强制转换成整型.
105.parseFloat(string[,radix])强制转换成浮点型.
106.isNaN(变量):测试是否为数值型.
107.定义常量的要害字:const,定义变量的要害字:var
posted @ 2009-11-23 00:04 星际迷茫 阅读(58) 评论(0) 编辑

这两个概念困扰了我很久,这次项目中需要,只能把它去搞懂了。

Monitor是一个C#中常用的同步代码的类。

首先要明白,Monitor维护两个队列,就绪队列和等待队列。就绪队列里面的线程会在其他线程A退出(Exit)或者A进入等待(Wait)的时候执行,而等待队列里面线程只会在其他线程A调用Pulse方法的时候被加到就绪队列中,然后在A调用Exit或者Wait的时候在执行。

Monitor.Enter 是获取排它锁。如果没有排它锁,它将会等待。直到其他占有锁的对象调用Monitor.Exit,或者Monitor.Wait方法。

Monitor.Wait和Monitor.Pulse的代码只能在Enter和Exit之间。

 

 

posted @ 2009-11-19 13:38 星际迷茫 阅读(499) 评论(0) 编辑
摘要: 今天观察一个代码的时候看到有一条语句if ((Session != null) && (!string.IsNullOrEmpty(Session.SessionID))) { ViewStateUserKey = Session.SessionID; }于是就进行了google,发现下面的文章。ViewStateUserKey从 ASP.NET 1.1 开始引入,ViewStat...阅读全文
posted @ 2009-11-17 23:57 星际迷茫 阅读(297) 评论(0) 编辑