关于怎么在10万个手机号码中选择重复号码的问题。
2011-07-21 18:40
495 查看
刚才看到这篇博客。
/article/7136226.html大家一般都认为用Hash的办法。不过其实还有更高效的算法。
计算机图形学中,有个八叉树量化法,是用来从24颜色中查找重复颜色,并且进行计数归并的算法。它的算法思想是八叉树一共8层,每层都有8个节点,每一条路径从根到页正好对应8个位.
而颜色RGB 三个数字正好可以拼成一个由0-7数字组成的8位数字,于是正好可以用八叉树算法进行插入。
比如:View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
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.ElapsedTicks );
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.ElapsedTicks);
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];
}
}
}
Linq共有重复号9000耗时139310
十叉树共有重复号9000耗时69545
如何?效率已达到Linq的1倍!
这还不算完,我们还没有使用Release模式呢!
Linq共有重复号9000耗时141970
十叉树共有重复号9000耗时35843
Release后,性能又提升1倍!
大家不妨用其他语言来实现下,比比效率如何?
C#还是很强的,HOHO
==================================
今天又做了测试,发现我家的老笔记本上,是十叉树占优,但是公司的电脑上是HashSet比较快。
不过十叉树应该还没有达到最优化,应该是分配节点时的开销过大导致。暂时想不出更好的优化方法-_-
==================================
五分钟后再次测试,十叉树只需在初始化时预先分配一个节点池,即可完胜HashSet.不过,此法或有胜之不武的嫌疑,哈哈。
也就是说,不算实例化的时间,十叉树胜,算实例化时间,哈希胜,
/article/7136226.html大家一般都认为用Hash的办法。不过其实还有更高效的算法。
计算机图形学中,有个八叉树量化法,是用来从24颜色中查找重复颜色,并且进行计数归并的算法。它的算法思想是八叉树一共8层,每层都有8个节点,每一条路径从根到页正好对应8个位.
而颜色RGB 三个数字正好可以拼成一个由0-7数字组成的8位数字,于是正好可以用八叉树算法进行插入。
比如:View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
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.ElapsedTicks );
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.ElapsedTicks);
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];
}
}
}
Linq共有重复号9000耗时139310
十叉树共有重复号9000耗时69545
如何?效率已达到Linq的1倍!
这还不算完,我们还没有使用Release模式呢!
Linq共有重复号9000耗时141970
十叉树共有重复号9000耗时35843
Release后,性能又提升1倍!
大家不妨用其他语言来实现下,比比效率如何?
C#还是很强的,HOHO
==================================
今天又做了测试,发现我家的老笔记本上,是十叉树占优,但是公司的电脑上是HashSet比较快。
不过十叉树应该还没有达到最优化,应该是分配节点时的开销过大导致。暂时想不出更好的优化方法-_-
==================================
五分钟后再次测试,十叉树只需在初始化时预先分配一个节点池,即可完胜HashSet.不过,此法或有胜之不武的嫌疑,哈哈。
也就是说,不算实例化的时间,十叉树胜,算实例化时间,哈希胜,
相关文章推荐
- 关于头文件变量重复定义问题怎么解决(thinkvd开发日志)
- 关于怎么用Xamarin来将JS通知转换成手机系统通知的问题
- 关于android 获取手机号码的问题
- 关于服务器获取手机号码的问题总结
- 关于目前更换手机而出现号码转移难的问题
- java excel读取的时候手机号码变成了数值类型的值,怎么防止这种问题
- 关于C# winform treeview 的两个问题(点击空白处的时间响应和复选框选择问题)
- EasyPusher手机直播图像旋转90度后画面重复的问题
- 关于J2ME调用手机拍照的程序问题
- 关于丢失手机的问题
- 关于安卓手机开机自启动APP无法成功的问题
- 关于手机号码、邮箱的在JavaScript中的正则表达式和其简单用法
- 关于字体大小随手机底层设置改变而改变的问题
- 关于读取Properties文件的相对路径问题,怎么写是正确的?
- 手机号码检测开通微信工具如何进行选择
- 关于springmvc 刷新action的方法重复提交的问题 重复执行
- 关于HTTP客户端重复发送请求的问题
- 关于各种牌子手机的字体问题
- 一个关于去除数组重复元素的问题(C语言实现)
- 关于android开发中手机连接不上eclipse问题