关于怎么在10万个手机号码中选择重复号码的问题(目前最高效的算法)

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

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

 

ExpandedBlockStart.gif View Code
Dictionary < int int >  dic  =   new  Dictionary < int int > ();
            
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是一样的。

效果:

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

 

所有代码

ExpandedBlockStart.gif 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( 0 4 ) : (i.ToString()  +   " 0000 " ).Substring( 0 4 ));
            }

            
/// /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
< int int >  dic  =   new  Dictionary < int int > ();
            
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 ];
        }


    }
}

 

 

转载于:https://www.cnblogs.com/Rousef/archive/2011/07/21/sjhmqcf.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值