超薄

 
 

Powered by: 博客园
模板提供:沪江博客
博客园 | 首页 | 发新随笔 | 发新文章 | 联系 | 订阅订阅 | 管理

2012年4月4日

并行算法中的异常
   public  class AsyncTask
{
public void TestMethod()
{
List<string> Listone = new List<string> { "url2","url","urle"};
//var results = from url in Listone.AsParallel()
// select new WebClient().DownloadData(url);
//results.ForAll(result=>Userresult(result));
try
{
Listone.RunAsync(url => StartDownload(url), task => FinishDownLoad(task.AsyncState.ToString(), task.Result));
}
catch(AggregateException problems)
{
var handers = new Dictionary<Type, Action<Exception>>();
handers.Add(typeof(Exception),ex=>Console.WriteLine(ex.Message));
if (!HandleAggregateError(problems, handers))
throw;
}

}
private static bool HandleAggregateError(AggregateException aggregate,Dictionary<Type,Action<Exception>> exceptionHanders)
{
foreach(var exception in aggregate.InnerExceptions)
{
if (exception is AggregateException)
return HandleAggregateError(exception as AggregateException, exceptionHanders);
else if (exceptionHanders.ContainsKey(exception.GetType()))
{
exceptionHanders[exception.GetType()](exception);
}
else
return false;


}
return true;
}

private void Userresult(byte[] result)
{
return;
}
private static void FinishDownLoad(string url,byte[] bytes)
{
Console.WriteLine("Read{0} byes from {1}",bytes.Length,url);
}
private static Task<byte[]> StartDownload(string url)
{
var tcs = new TaskCompletionSource<byte[]>(url);
var wc = new WebClient();
wc.DownloadDataCompleted += (sender, e) =>
{
if (e.UserState == tcs)
{
if (e.Cancelled)
{
tcs.TrySetCanceled();
}
else if (e.Error != null)
{
if (e.Error is WebException)
tcs.TrySetResult(new byte[0]);
else
tcs.TrySetException(e.Error);
}
else
tcs.TrySetResult(e.Result);
}

};

wc.DownloadDataAsync(new Uri(url),tcs);
return tcs.Task;
}
}
public static class MyExtenion
{
public static void RunAsync<T, TResult>(this IEnumerable<T> taskParms, Func<T, Task<TResult>> tasStarter, Action<Task<TResult>> taskFinisher)
{
taskParms.Select(parm => tasStarter(parm)).AsParallel().ForAll(t => t.ContinueWith(t2 => taskFinisher(t2)));

}
}

 

posted @ 2012-04-04 15:45 超薄 阅读(13) 评论(0) 编辑
 
事件模式实现通知
class LoggerClass
{
}
public class LoggerEventArgs : EventArgs
{
public string Message { get; private set; }
public int Priority { get; private set; }
public LoggerEventArgs(int priority,string msg)
{
Priority = priority;
Message = msg;

}

}
public static struct LogerEventName
{
public static readonly string OnError = "OnError";
public static readonly string OnFail = "OnFail";
public static readonly string OnWaring = "OnWaring";

}

public sealed class Logger
{
private static Dictionary<string, EventHandler<LoggerEventArgs>> Handers = new Dictionary<string, EventHandler<LoggerEventArgs>>();
public static void AddLoger(string system,EventHandler<LoggerEventArgs> ev)
{
if (Handers.ContainsKey(system))
{
Handers[system] += ev;
}
else
{
Handers.Add(system,ev);
}
}
public static void RemoveLogger(string system,EventHandler<LoggerEventArgs> ev)
{
if (Handers.ContainsKey(system))
{
Handers[system] -= ev;
}
}

public static void AddMsg(string sytem,int priority,string msg)
{
if (string.IsNullOrEmpty(sytem) || !Handers.ContainsKey(sytem))
return;
LoggerEventArgs args = new LoggerEventArgs(priority,msg);
EventHandler<LoggerEventArgs> eventthander = null;
Handers.TryGetValue(sytem, out eventthander);
if (eventthander != null)
eventthander(null, args);
}
}

 

posted @ 2012-04-04 15:42 超薄 阅读(11) 评论(0) 编辑
 
扩展属性应用

字段去除空格

代码

 [AttributeUsage(AttributeTargets.Property,Inherited=false,AllowMultiple=false)]
public class TrimAttribute:Attribute
{ private readonly Type type;
public TrimAttribute(Type type)
{
this.type = type;
}
public Type Type
{
get { return this.type; }
}
}
public static class TrimAttributeExtension
{
public static void Trim(this Object obj)
{
Type t = obj.GetType();
foreach(var prop in t.GetProperties())
{
foreach(var attr in prop.GetCustomAttributes(typeof(TrimAttribute),true))
{
TrimAttribute tsa = (TrimAttribute)attr;
if(prop.GetValue(obj,null)!=null&&(tsa.Type==typeof(string)))
{
prop.SetValue(obj,GetPropertyValue(obj,prop.Name).ToString().Trim(),null);
}
}
}
}
private static object GetPropertyValue(object instance,string PropertName)
{
return instance.GetType().InvokeMember(PropertName,System.Reflection.BindingFlags.GetProperty,null,instance,new Object[]{});
}
}

使用

  public class SomeClass
{ [Trim(typeof(string))]
string Name { get; set; }
}


查询语法

 public  class SelectClass
{
public void Method1()
{
int[] fool=new int[100];
for (int num = 0; num < fool.Length; num++)
{
fool[num] = num * num;
}
foreach(int i in fool)
{
Console.WriteLine(i.ToString());
}
}
public void Method1Select()
{
int[] fool = (from n in Enumerable.Range(0, 100) select n * n).ToArray();
fool.ForAll((n) => Console.WriteLine(n));
}
public IEnumerable<Tuple<int, int>> ProduceIndices()
{
for (int x = 0; x < 100; x++)
for (int y = 0; y < 100; y++)
if (x + y < 100)
yield return Tuple.Create(x,y);
}
public IEnumerable<Tuple<int, int>> ProduceIndicesSelect()
{
return from x in Enumerable.Range(0, 100)
from y in Enumerable.Range(0, 100)
where x + y < 100
select Tuple.Create(x,y);
}
}

public static class Extensions
{
public static void ForAll<T>(this IEnumerable<T> sequence, Action<T> action)
{
foreach(T item in sequence)
{
action(item);
}
}
}



posted @ 2012-04-04 15:37 超薄 阅读(5) 评论(0) 编辑
 

2012年2月16日

位运算应用口诀和实例(转自大笨狼)

位运算应用口诀和实例
 
位运算应用口诀 
清零取反要用与,某位置一可用或
若要取反和交换,轻轻松松用异或
移位运算
要点 1 它们都是双目运算符,两个运算分量都是整形,结果也是整形。
  2 "<<" 左移:右边空出的位上补0,左边的位将从字头挤掉,其值相当于乘2。
  3 ">>"右移:右边的位被挤掉。对于左边移出的空位,如果是正数则空位补0,若为负数,可能补0或补1,这取决于所用的计算机系统。
  4 ">>>"运算符,右边的位被挤掉,对于左边移出的空位一概补上0。
位运算符的应用 (源操作数s 掩码mask)
(1) 按位与-- &
1 清零特定位 (mask中特定位置0,其它位为1,s=s&mask)
2 取某数中指定位 (mask中特定位置1,其它位为0,s=s&mask)
(2) 按位或-- |
  常用来将源操作数某些位置1,其它位不变。 (mask中特定位置1,其它位为0 s=s|mask)
(3) 位异或-- ^
1 使特定位的值取反 (mask中特定位置1,其它位为0 s=s^mask)
2 不引入第三变量,交换两个变量的值 (设 a=a1,b=b1)
  目 标 操 作 操作后状态
a=a1^b1 a=a^b a=a1^b1,b=b1
b=a1^b1^b1 b=a^b a=a1^b1,b=a1
a=b1^a1^a1 a=a^b a=b1,b=a1
二进制补码运算公式:
-x = ~x + 1 = ~(x-1)
~x = -x-1 
-(~x) = x+1
~(-x) = x-1
x+y = x - ~y - 1 = (x|y)+(x&y) 
x-y = x + ~y + 1 = (x|~y)-(~x&y) 
x^y = (x|y)-(x&y)
x|y = (x&~y)+y
x&y = (~x|y)-~x
x==y: ~(x-y|y-x)
x!=y: x-y|y-x
x< y: (x-y)^((x^y)&((x-y)^x))
x<=y: (x|~y)&((x^y)|~(y-x))
x< y: (~x&y)|((~x|y)&(x-y))//无符号x,y比较
x<=y: (~x|y)&((x^y)|~(y-x))//无符号x,y比较
应用举例
(1) 判断int型变量a是奇数还是偶数  
a&1 = 0 偶数
  a&1 = 1 奇数
(2) 取int型变量a的第k位 (k=0,1,2……sizeof(int)),即a>>k&1
(3) 将int型变量a的第k位清0,即a=a&~(1<<k)
(4) 将int型变量a的第k位置1, 即a=a|(1<<k)
(5) int型变量循环左移k次,即a=a<<k|a>>16-k (设sizeof(int)=16)
(6) int型变量a循环右移k次,即a=a>>k|a<<16-k (设sizeof(int)=16)
(7)整数的平均值
对于两个整数x,y,如果用 (x+y)/2 求平均值,会产生溢出,因为 x+y 可能会大于INT_MAX,但是我们知道它们的平均值是肯定不会溢出的,我们用如下算法:
int average(int x, int y) //返回X,Y 的平均值
{  
  return (x&y)+((x^y)>>1);
}
(8)判断一个整数是不是2的幂,对于一个数 x >= 0,判断他是不是2的幂
boolean power2(int x)
{
  return ((x&(x-1))==0)&&(x!=0);
}
(9)不用temp交换两个整数
void swap(int x , int y)
{
  x ^= y;
  y ^= x;
  x ^= y;
}
(10)计算绝对值
int abs( int x ) 
{
int y ;
y = x >> 31 ;
return (x^y)-y ; //or: (x+y)^y
}
(11)取模运算转化成位运算 (在不产生溢出的情况下)
  a % (2^n) 等价于 a & (2^n - 1)
(12)乘法运算转化成位运算 (在不产生溢出的情况下)
  a * (2^n) 等价于 a<< n
(13)除法运算转化成位运算 (在不产生溢出的情况下)
  a / (2^n) 等价于 a>> n
  例: 12/8 == 12>>3
(14) a % 2 等价于 a & 1  
(15) if (x == a) x= b;
   else x= a;
   等价于 x= a ^ b ^ x;
(16) x 的 相反数 表示为 (~x+1) 


实例

  功能 | 示例 | 位运算
----------------------+---------------------------+--------------------
去掉最后一位 | (101101->10110) | x >> 1
在最后加一个0 | (101101->1011010) | x << 1
在最后加一个1 | (101101->1011011) | x << 1+1
把最后一位变成1 | (101100->101101) | x | 1
把最后一位变成0 | (101101->101100) | x | 1-1
最后一位取反 | (101101->101100) | x ^ 1
把右数第k位变成1 | (101001->101101,k=3) | x | (1 << (k-1))
把右数第k位变成0 | (101101->101001,k=3) | x & ~ (1 << (k-1))
右数第k位取反 | (101001->101101,k=3) | x ^ (1 << (k-1))
取末三位 | (1101101->101) | x & 7
取末k位 | (1101101->1101,k=5) | x & ((1 << k)-1)

取右数第k位 | (1101101->1,k=4) | x >> (k-1) & 1

把末k位变成1 | (101001->101111,k=4) | x | (1 << k-1)
末k位取反 | (101001->100110,k=4) | x ^ (1 << k-1)
把右边连续的1变成0 | (100101111->100100000) | x & (x+1)
把右起第一个0变成1 | (100101111->100111111) | x | (x+1)
把右边连续的0变成1 | (11011000->11011111) | x | (x-1)
取右边连续的1 | (100101111->1111) | (x ^ (x+1)) >> 1
去掉右起第一个1的左边 | (100101000->1000) | x & (x ^ (x-1))
判断奇数 (x&1)==1
判断偶数 (x&1)==0  

posted @ 2012-02-16 13:09 超薄 阅读(21) 评论(0) 编辑
 

2012年2月15日

数据结构实际应用----订单排序(堆排序求前N大)

1.堆排序思想
堆排序是一种树形选择排序,在排序过程中,将A[1..n]看成是完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系来选择最小的元素。
2.堆的定义:n个元素的序列K1,K2,K3,…Kn称为堆,当且仅当该序列满足特性:Ki≤K2i , Ki ≤K2i+1(1≤i≤n/2)
堆实质上是满足如下性质的完全二叉树:树中任一非叶子结点的关键字均大于等于其孩子结点的关键字。例如序列{1,35,14,60,61,45,15,81}就是一个堆,它对应的完全二叉树如下图1所示。这种堆中根结点(称为堆顶)的关键字最小,我们把它称为小根堆。反之,若完全二叉树中任一非叶子结点的关键字均大于等于其孩子的关键字,则称之为大根堆。

    

 下面的例子用大根堆来实现订单排序

 思路是保持前K大有序,然后插入时候判断,非大不插,并且插入的时候是二分查找位置,弹出最后一个

订单结构

  public struct Order:IComparable<Order>
{
public DateTime CreateTime;
public string Name;
public decimal Total;
public int OrderDetailCount;
private static IComparer<Order> _compare;
public Order(string name,DateTime createTime,decimal total,int orderdetailCocunt)
{
Name = name;
CreateTime = createTime;
Total = total;
OrderDetailCount = orderdetailCocunt;
}

public int CompareTo(Order other)
{
return string.Compare(Name, other.Name);
}
public static IComparer<Order> SortByTime()
{
return new TimeCompare();
}
public static IComparer<Order> SortByTotal()
{
return new TotalComare();
}
public static IComparer<Order> SortByOrderDetail()
{
return new OrderDetailCompare();
}
public static bool operator >=(Order left,Order right)
{
return left.CompareTo(right)>=0;
}
public static bool operator <=(Order left, Order right)
{
return left.CompareTo(right) <= 0;
}
public static bool operator >(Order left, Order right)
{
return left.CompareTo(right) > 0;
}
public static bool operator<(Order left, Order right)
{
return left.CompareTo(right) <0;
}

}
   public  class TimeCompare : IComparer<Order>
        {

            public int Compare(Order x, Order y)
            {
                return x.CreateTime.CompareTo(x.CreateTime);
            }
        }
        public class TotalComare : IComparer<Order>
      {
          public int Compare(Order x, Order y)
          {
              return x.Total.CompareTo(y.Total);
          }
      }
        public  class OrderDetailCompare : IComparer<Order>
      {

          public int Compare(Order x, Order y)
          {
              return x.OrderDetailCount.CompareTo(y.OrderDetailCount);
          }
      }

 堆排类

 public class HeapSort
{
private int heapSize = 0;
public Order[] Heap;
public int Count = 0;
IComparer<Order> SelfCompare;
public HeapSort(int size,IComparer<Order> compare)
{ heapSize = size;
Heap = new Order[size];
SelfCompare = compare;
}

public void Insert(Order iterm)
{
if (SelfCompare.Compare(iterm, Heap[heapSize - 1]) > 0)
{
Insert(iterm, 0, (Heap.Length - 1) / 2, Heap.Length - 1);
}
Count++;
}

private void Insert(Order iterm, int min, int pos, int max)
{

if ((SelfCompare.Compare(iterm, Heap[pos]) <= 0 && SelfCompare.Compare(iterm,Heap[pos + 1]) >= 0) || pos == 0)
{
for (int i = heapSize - 1; i > pos; i--)
{
Heap[i] = Heap[i - 1];
}
if (pos == 0)
{
Heap[pos] = iterm;
}
else
{
Heap[pos + 1] = iterm;
}
}
else
{
if (iterm.CompareTo(Heap[pos]) > 0)
{
max = pos;
}
else
{
min = pos;
}
pos = Convert.ToInt32((max + min) / 2);
Insert(iterm, min, pos, max);
}
}



}

测试代码

  static void Main(string[] args)
{
HeapSort mySort = new HeapSort(1000,new TimeCompare());
Random Rand = new Random();
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
for (int i = 0; i < 1000 * 1000; i++)
{
Order temporder = new Order("Product"+i, DateTime.Now.AddMinutes(Rand.Next()),i,Rand.Next());
mySort.Insert(temporder);
}
sw.Stop();

Console.WriteLine(sw.ElapsedMilliseconds);

for (int i = 0; i < mySort.Heap.Length; i++)
{
Order iterm = mySort.Heap[i];

Console.WriteLine(iterm.Name);
}
Console.WriteLine("长度:" + mySort.Count + "-------------------------------");
Console.Read();

}

百万订单实际需要30毫秒,时间复杂度 大致可看做o(n).

posted @ 2012-02-15 14:06 超薄 阅读(89) 评论(0) 编辑
 

2012年2月13日

数据结构Tire 树实际应用----过滤禁词

又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来节约存储空间,最大限度地减少无谓的字符串比较,查询效率比哈希表高。

 

 

它有3个基本性质:

 

  根节点不包含字符,除根节点外每一个节点都只包含一个字符。 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。 每个节点的所有子节点包含的字符都不相同。

 

基本操作

  其基本操作有:查找 插入和删除,当然删除操作比较少见.我在这里只是实现了对整个树的删除操作,至于单个word的删除操作也很简单.

 

  

namespace ConsoleApplication1
{
public class TireTree
{
private TireNode root = new TireNode(' ');
public TireTree()
{

}
private void CreateTireTree(TireNode node, string word, int index)
{
if (word.Length == index) return;
char key = word[index];
TireNode newNode = null;
if (node.NextNode.ContainsKey(key))
{
newNode = node.NextNode[key];
}
else
{
newNode = new TireNode(key);
node.NextNode.Add(key, newNode);
}
if (word.Length - 1 == index)
{
newNode.Word = word;
}
CreateTireTree(node.NextNode[key], word, index + 1);
}

public void AddWords(string word)
{
CreateTireTree(root, word, 0);
}
public List<string> SearchWords(string content)
{
List<string> result = new List<string>();
char[] charArr = content.ToCharArray();
TireNode currentNode = root;
for (int i = 0; i < charArr.Length; i++)
{
if (currentNode.NextNode.ContainsKey(charArr[i])) //如果下个节点找得到当前字,则继续往下找下个字符。
{
currentNode = currentNode.NextNode[charArr[i]];
}
else if (root.NextNode.ContainsKey(charArr[i])) //如果下个节点找不到当前字,则从根节点找。
{
currentNode = root.NextNode[charArr[i]];
}
else //否则下个字符,也从根节点找。
{
currentNode = root;
}
if (currentNode.IsWord)
{
if (!result.Contains(currentNode.Word))
result.Add(currentNode.Word);
}
}

return result;
}
private class TireNode
{
public char Key { get; set; }
public string Word { get; set; }
public bool IsWord { get { return this.Word != null; } }
private Dictionary<char, TireNode> nextNode = new Dictionary<char, TireNode>();
public Dictionary<char, TireNode> NextNode
{
get { return nextNode; }
set { nextNode = value; }
}

public TireNode(char key)
{
this.Key = key;
}

}
}
}


实现方法

  搜索字典项目的方法为(1) 从根结点开始一次搜索;

 

  (2) 取得要查找关键词的第一个字母,并根据该字母选择对应的子树并转到该子树继续进行检索;

 

  (3) 在相应的子树上,取得要查找关键词的第二个字母,并进一步选择对应的子树进行检索。

 

  (4) 迭代过程……

 

  (5) 在某个结点处,关键词的所有字母已被取出,则读取附在该结点上的信息,即完成查找。

 

   测试代码

    private void TestTireTree()
{ const int count=100;
string[] Arr = new string[count]; for (int i = 0; i < Arr.Length; i++) { Arr[i] = (Guid.NewGuid()).ToString(); } // 这里是只是演示放入字符,建立Tire树

TireTree Tree = new TireTree();

foreach (string str in Arr)
{
Tree.AddWords(str );
}
string word = "检测的字符";
List<string> ResultList= Tree.SearchWords(word);
foreach(string result in ResultList)
{
Console.WriteLine(string.Format("检测到非法词语{0}"),result);
}

}

代码中 CreateTireTree(TireNode node, string word, int index) 使用递归实现的,可以修改回溯版本,提高效率。

  private void CreateArrayTireTree(TireNode node, string word)
{
char[] wordsarray = word.ToCharArray();
for (int i = 0; i < wordsarray.Length; i++)
{
char key = word[i];
TireNode newNode = null;
if (node.NextNode.ContainsKey(key))
{
newNode = node.NextNode[key];
}
else
{
newNode = new TireNode(key);
node.NextNode.Add(key, newNode);
}
if (i == wordsarray.Length - 1)
{
newNode.Word = word;
}

node = node.NextNode[key];
}


}

 

posted @ 2012-02-13 17:55 超薄 阅读(1005) 评论(2) 编辑
 

2012年2月11日

快速排序算法

快速排序算法是最快的排序算法,当然它是针对大量通常无序的集合而言是正确的。

public void QSort()

{

    RecQSort(0, numElements - 1);

}

public void RecQSort(int first, int last)

{

    if ((last - first) <= 0)

        return;

    else

    {

        int part = this.Partition(first, last);

        RecQSort(first, part - 1);

        RecQSort(part + 1, last);

    }

}

public int Partition(int first, int last)

{

    int pivotVal = arr[first];

    int theFirst = first;

    bool okSide;

    first++;

    do

    {

        okSide = true;

        while (okSide)

            if (arr[first] > pivotVal)

                okSide = false;

            else

            {

                first++;

                okSide = (first <= last);

            }

        okSide = true;

        while (okSide)

            if (arr[last] <= pivotVal)

                okSide = false;

            else

            {

                last--;

                okSide = (first <= last);

            }

        if (first < last)

        {

            Swap(first, last);

            this.DisplayElements();

            first++;

            last--;

        }

    } while (first <= last);

    Swap(theFirst, last);

    this.DisplayElements();

    return last;

}

public void Swap(int item1, int item2)

{

    int temp = arr[item1];

    arr[item1] = arr[item2];

    arr[item2] = temp;

}

如果数组内的的数据是随机的,那么选择第一个

最流行的选择中间值得方法。

theFirst = arr[(int)arr.GetUpperBound(0) / 2]

posted @ 2012-02-11 20:17 超薄 阅读(22) 评论(0) 编辑
 
动态规划

动态规划认为是递归的反向技术,递归的效率低下。

斐波那契数列 0 ,1,2,3,5,8,13,21,34

 

static long recurFib(int n) 

{

if (n < 2)

        return n;

else

        return recurFib(n - 1) + recurFib(n - 2);

}

 

 

动态规划版本 

 

    static long iterFib(int n)

    {

        int[] val = new int[n];

        if ((n == 1) || (n == 2))

            return 1;

        else

        {

            val[1] = 1;

            val[2] = 2;

            for (int i = 3; i <= n - 1; i++)

                val[i] = val[i - 1] + val[i - 2];

        }

        return val[n - 1];

}

 

static void Main()

{

Timing tObj = new Timing();

    Timing tObj1 = new Timing();

    int num = 35;

    long fibNumber;

    tObj.startTime();

    fibNumber = recurFib(num);

    tObj.stopTime();

    Console.WriteLine("Calculating Fibonacci number: " + num);

    Console.WriteLine(fibNumber + " in: " + tObj.Result().TotalMilliseconds);

    tObj1.startTime();

    fibNumber = iterFib(num);

    tObj1.stopTime();

    Console.WriteLine(fibNumber + " in: " + tObj1.Result().TotalMilliseconds);

}

随着数字增大,效率差距很大。

posted @ 2012-02-11 20:17 超薄 阅读(18) 评论(0) 编辑
 
字典 DictionaryBase 和 SortedList

字典是一种利用键值对来存储的数据结构。作为一种抽象类,dictionaryBase 类可以实现不同的结构

sortedList 是按照分类顺序基于键值来存储键值对的,它可以通过引用数据结构中的值得索引位置也可以访问存贮在结构中的数据。

Dictionary 中,存储在字段中的键值对于时间上最为 DictionaryEntry 对象来存储的。DictionaryEntry 结构提供两个域,一个用于键,一个用于值。对于内部而言会把键值存储在innerHashTable  的散列对象中。

 

public class IPAddresses : DictionaryBase

{

    public IPAddresses()

    {

    }

    public void Add(string name, string ip)

    {

        base.InnerHashtable.Add(name, ip);

    }

    public string Item(string name)

    {

        return base.InnerHashtable[name].ToString();

    }

    public void Remove(string name)

    {

        base.InnerHashtable.Remove(name);

    }

}

  static void Main()

    {

        IPAddresses myIPs = new IPAddresses();

        myIPs.Add("Mike", "192.155.12.1");

        myIPs.Add("David", "192.155.12.2");

        myIPs.Add("Bernica", "192.155.12.3");

        Console.WriteLine("There are " + myIPs.Count + " IP addresses");

        Console.WriteLine("David's ip address: " + myIPs.Item("David"));

        myIPs.Clear();

        Console.WriteLine("There are " + myIPs.Count + " IP addresses");

    }

class chapter

{

    static void Main()

    {

        for (int i = 0; i < 4; i++)

            Console.WriteLine();

        IPAddresses myIPs = new IPAddresses(@"c:\data\ips.txt");

        Console.WriteLine("There are {0} IP addresses", myIPs.Count);

        Console.WriteLine("David's IP address: " + myIPs.Item("David"));

        Console.WriteLine("Bernica's IP address: " + myIPs.Item("Bernica"));

        Console.WriteLine("Mike's IP address: " + myIPs.Item("Mike"));

    }

}

 

 

IPAddresses myIPs = new IPAddresses(@"c:\ips.txt");

DictionaryEntry[] ips = new DictionaryEntry[myIPs.Count-1];

myIPs.CopyTo(ips, 0);

 

 

泛型KeyValuePair 类,每个对象只能存储一个值

<string, int> mcmillan = new KeyValuePair<string, int>("McMillan", 99);

Console.Write(mcmillan.Key);

Console.Write(" " + mcmillan.Value);

 

 

using System;

using System.Collections.Generic;

using System.Text;

namespace Generics

{

    class Program

    {

        static void Main(string[] args)

        {

 

            KeyValuePair<string, int>[] gradeBook = new KeyValuePair<string, int>[10];

            gradeBook[0] = new KeyValuePair<string,int>("McMillan", 99);

            gradeBook[1] = new KeyValuePair<string,int>("Ruff", 64);

            for (int i = 0; i <= gradeBook.GetUpperBound(0); i++)

                if (gradeBook[i].Value != 0)

                    Console.WriteLine(gradeBook[i].Key + ": " + gradeBook[i].Value);

            Console.Read();

        }

    }

}

 

SortedList 类

 

SortedList myips = new SortedList();

myips.Add("Mike", "192.155.12.1");

myips.Add("David", "192.155.12.2");

myips.Add("Bernica", "192.155.12.3");

 

 

SortedList<Tkey, TValue>

 

 

SortedList<string, string> myips = new SortedList<string, string>();

 

SortedList<string, int> gradeBook = new SortedList<string, int>();

 

 

foreach(Object key in myips.Keys)

Console.WriteLine("Name: " + key + "\n" + "IP: " + myips[key]);

 

for(int i = 0; i < myips.Count; i++)

Console.WriteLine("Name: " + myips.GetKey(i) + "\n" + "IP: " + myips.GetByIndex(i));

 

myips.Remove("David");

myips.RemoveAt(1);

int indexDavid = myips.IndexOfKey("David");

int indexIPDavid = myips.IndexOfValue(myips["David"]);

 

散列和HasTable

散列是一种常见的顺出数据技术,采用这种技术可以非常迅速的插入和检索数据。散列所采用的数据结构成为散列表。

 

 

 散列表数据结构是围绕数组设计的。存储在数组内的每一个数据读书基于键映射到一个范围从0到散列表大小的数值上,这被称为是键,为了把一个元素存储到散列表内,利用所谓散列函数吧键映射到一个范围从0到散列表大小的数上。由于键是不受限制的,而数组的大小又是有限制的,所以散列函数比较现实的目标是把键尽可能平均分布到数组的单元内。即使一个很好的散列函数也可能会出现两个键散列到相同的数值情况,这种现象称为冲突。

 

选择散列函数 

 选择散列函数的依据是所用键的数据类型。如果所用的键是整数,那么最简单的函数是返回键对数组大小取莫结果(前提是数组的大小必须是素数)。然而许多应用中键都是字符串,下面一个简单利用把键内字母Ascll码相加,上述加和的数值与数组大小模莫就是散列值了。

 

 

using System;

class chapter

{

    static void Main()

    {

        string[] names = new string[99];

        string name;

        string[] someNames = new string[]{"David","Jennifer", "Donnie", "Mayo", "Raymond",

            "Bernica", "Mike", "Clayton", "Beata", "Michael"};

        int hashVal;

        for (int i = 0; i < 10; i++)

        {

            name = someNames[i];

            hashVal = SimpleHash(name, names);

            names[hashVal] = name;

        }

        ShowDistrib(names);

    }

    static int SimpleHash(string s, string[] arr)

    {

        int tot = 0;

        char[] cname;

        cname = s.ToCharArray();

        for (int i = 0; i <= cname.GetUpperBound(0); i++)

            tot += (int)cname[i];

        return tot % arr.GetUpperBound(0);

    }

    static void ShowDistrib(string[] arr)

    {

        for (int i = 0; i <= arr.GetUpperBound(0); i++)

            if (arr[i] != null)

                Console.WriteLine(i + " " + arr[i]);

    }

}

问题出现了,键分布不均匀都聚集在数组的开始和结束处。

最终选择数组的小取决于存储在记录的确切数量。一个保险数字是10007,它是素数,而且还没大到,会使用大量内存导致降低程序性能的地步。

一个好的解决方法

static int BetterHash(string s, string[] arr)

{

    long tot = 0;

    char[] cname;

    cname = s.ToCharArray();

    for (int i = 0; i <= cname.GetUpperBound(0); i++)

        tot += 37 * tot + (int)cname[i];

    tot = tot % arr.GetUpperBound(0);

    if (tot < 0)

        tot += arr.GetUpperBound(0);

    return (int)tot;

}

这个函数利用霍纳法则(Horner)来计算多项式函数。

 

查找散列表中数据

static bool InHash(string s, string[] arr)

{

    int hval = BetterHash(s, arr);

    if (arr[hval] == s)

        return true;

    else

        return false;

}

 

解决冲突 

 在处理散列表的时候,不可避免的会遇到这种情况,即计算出的键的散列值已经存储到了赢一个键,这个就是所谓的冲突。

筒式散列法

public class BucketHash

{

    private const int SIZE = 101;

    ArrayList[] data;

    public BucketHash()

    {

        data = new ArrayList[SIZE];

        for (int i = 0; i <= SIZE - 1; i++)

            data[i] = new ArrayList(4);

    }

    public int Hash(string s)

    {

        long tot = 0;

        char[] charray;

        charray = s.ToCharArray();

        for (int i = 0; i <= s.Length - 1; i++)

            tot += 37 * tot + (int)charray[i];

        tot = tot % data.GetUpperBound(0);

        if (tot < 0)

            tot += data.GetUpperBound(0);

        return (int)tot;

    }

    public void Insert(string item)

    {

        int hash_value;

        hash_value = Hash(item);

        if (data[hash_value].Contains(item))

            data[hash_value].Add(item);

    }

    public void Remove(string item)

    {

        int hash_value;

        hash_value = Hash(item);

        if (data[hash_value].Contains(item))

            data[hash_value].Remove(item);

    }

}

 

 

堆排序 

如果将堆看成是一棵完全二叉树,则这棵完全二叉树每个非叶子节点的值均不大于(或不小于)其左,右孩子节点的值。非叶子节点大于左右节点值得堆称为大根堆,小于左右节点的值得堆称为小根堆。

堆的结构类似于二叉树,但是又不完全相同。首先构造堆通常采用的是数组而不是节点引用。

堆有两个非常重要的条件 (1)堆必须是完整的,这就是意味着每一行都必须有数据填充。(2)每个节点包含的数据大于或者等于此节点下方孩子节点所包含的数据。

 

using System;

public class Node

{

    public int data;

    public Node(int key)

    {

        data = key;

    }

}

 

 

public bool Insert(int key)

{

    if (currSize == maxSize)

        return false;

    heapArray[currSize] = new Node(key);

    currSize++;

    return true;

}

 

public void ShiftUp(int index) // 移动合适位置。

{

    int parent = (index - 1) / 2;

    Node bottom = heapArray[index];

    while ((index > 0) && (heapArray[parent].data < bottom.data))

    {

        heapArray[index] = heapArray[parent];

        index = parent;

        parent = (parent - 1) / 2;

    }

    heapArray[index] = bottom;

}

 

public Node Remove()

{

    Node root = heapArray[0];

    currSize--;

    heapArray[0] = heapArray[currSize];

    ShiftDown(0);

    return root;

}

public void ShiftDown(int index)

{

    int largerChild;

    Node top = heapArray[index];

    while (index < (int)(currSize / 2))

    {

        int leftChild = 2 * index + 1;

        int rightChild = leftChild + 1;

        if ((rightChild < currSize) && heapArray[leftChild].data < heapArray[rightChild].data)

            largerChild = rightChild;

        else

            largerChild = leftChild;

        if (top.data >= heapArray[largerChild].data)

            break;

        heapArray[index] = heapArray[largerChild];

        index = largerChild;

    }

    heapArray[index] = top;

}

 

public class Heap

{

    Node[] heapArray = null;

    private int maxSize = 0;

    private int currSize = 0;

    public Heap(int maxSize)

    {

        this.maxSize = maxSize;

        heapArray = new Node[maxSize];

    }

public bool InsertAt(int pos, Node nd)

{

        heapArray[pos] = nd;

        return true;

}

    public void ShowArray()

    {

        for (int i = 0; i < maxSize; i++)

        {

            if (heapArray[i] != null)

                System.Console.Write(heapArray[i].data + "  ");

        }

    }

    static void Main()

    {

        const int SIZE = 9;

        Heap aHeap = new Heap(SIZE);

        Random RandomClass = new Random();

        for (int i = 0; i < SIZE; i++)

        {

 

            int rn = RandomClass.Next(1, 100);

            aHeap.Insert(rn);

        }

        Console.Write("Random: ");

        aHeap.ShowArray();

        Console.WriteLine();

        Console.Write("Heap: ");

        for (int i = (int)SIZE / 2 - 1; i >= 0; i--)

            aHeap.ShiftDown(i);

        aHeap.ShowArray();

        for (int i = SIZE - 1; i >= 0; i--)

        {

            Node bigNode = aHeap.Remove();

            aHeap.InsertAt(i, bigNode);

        }

        Console.WriteLine();

        Console.Write("Sorted: ");

        aHeap.ShowArray();

    }

}

posted @ 2012-02-11 20:16 超薄 阅读(36) 评论(0) 编辑
 
模式匹配文本处理

使用正则表达式在System.TextRegularExpression

 

 

using System;

using System.Text.RegularExpressions;

class chapter8

{

    static void Main()

    {

        Regex reg = new Regex("the");

        string str1 = "the quick brown fox jumped over the lazy dog";

        Match matchSet;

        int matchPos;

        matchSet = reg.Match(str1);

        if (matchSet.Success)

        { 

            matchPos = matchSet.Index;

            Console.WriteLine("found match at position:" + matchPos);

        }

    }

}

 

if (Regex.IsMatch(str1, "the"))

{

    Match aMatch;

aMatch = reg.Match(str1);

 

using System;

using System.Text.RegularExpressions;

class chapter8

{

    static void Main()

    {

        Regex reg = new Regex("the");

        string str1 = "the quick brown fox jumped over the lazy dog";

        MatchCollection matchSet;

        matchSet = reg.Matches(str1);

        if (matchSet.Count > 0)

            foreach (Match aMatch in matchSet)

                Console.WriteLine("found a match at: " + aMatch.Index);

        Console.Read();

    }

}

 

数量词

(+)这个数量词说明正则表达式应该匹配一个或者多次紧接其前的字符。

(*)这个数量词说明正则表达式应该匹配零个或者多次紧接其前的字符。//实践中非常难用,会导致匹配太多

(?)这个数量词说明正则表达式应该匹配零次或者多次紧接其前的字符。

{N} 这个数量词指定要匹配的数量。

{m,n}这个数量词指定最小,做大匹配数量。也可以{m,},{,n}只指定最大和最小。

 

 

using System;

using System.Text.RegularExpressions;

class chapter8

{

    static void Main()

    {

        string[] words = new string[]{"Part", "of", "this","<b>string</b>", "is", "bold"};

        string regExp = "<.*>"; // 应该修改成 <.+?>  +仅使用这个是不行的。. (.)句点表示与任意字符匹配

        MatchCollection aMatch;

        foreach (string word in words)

        {

            if (Regex.IsMatch(word, regExp))

            {

                aMatch = Regex.Matches(word, regExp);

                for (int i = 0; i < aMatch.Count; i++)

                    Console.WriteLine(aMatch[i].Value);

            }

        }

    }

}

原本期望这个程序就返回两个标签:<b>和</b>  但由于贪心,正则返回了<b>string</b> 。利用惰性量词(?) 可以解决 <.+?> 仅适用+ 是不行的,必须加惰性量词?

使用字符类

句点(.)的通常是用它在字符内部定义字符范围,也就是用来限定字符串的开始/结束字符。

句点匹配任意字符。

using System;

using System.Text.RegularExpressions;

class chapter8

{

    static void Main()

    {

        string str1 = "the quick brown fox jumped over the lazy dog one time";

        MatchCollection matchSet;

        matchSet = Regex.Matches(str1, "t.e");

        foreach (Match aMatch in matchSet)

            Console.WriteLine("Matches at: " + aMatch.Index);

    }

}

 

 

检查字符组的模式 ,([])。在方括号内的字符称为“字符类”

using System;

using System.Text.RegularExpressions;

class chapter8

{

    static void Main()

    {

        string str1 = "THE quick BROWN fox JUMPED over THE lazy DOG";

        MatchCollection matchSet;

        matchSet = Regex.Matches(str1, "[a-z]");

        foreach (Match aMatch in matchSet)

            Console.WriteLine("Matches at: " + aMatch.Index);

    }

}

[]A-Za-z] 所有英文字母大小写

字符类前面放(^) 表示字符类的反或者否定如[aeiou] 表示元音,那么[^aeiou]表示非元音。

[]A-Za-z0-9 ]表示单词,也可以用\w表示,用\W表示\w的反向即非单词。

[0-9]可以用\d 表示

[^0-9] 表示\D 

\s 表示空格 \S表示非空格。

 

断言

(^) 在开始处匹配

($) 在结束处匹配

\b 在开始结束匹配

using System;

using System.Text.RegularExpressions;

class chapter8

{

    static void Main()

    {

        string[] words = new string[] { "heal", "heel", "noah", "techno" };

        string regExp = "^h";

        Match aMatch;

        foreach (string word in words)

            if (Regex.IsMatch(word, regExp))

            {

                aMatch = Regex.Match(word, regExp);

                Console.WriteLine("Matched: " + word + " at position: " + aMatch.Index);

            }

    }

}

 

string regExp = "h$";

string words = "hark, what doth thou say, Harold? ";

string regExp = "\\bh";

 

 使用分组构造 

 1 匿名分组

通过括号内围绕的正则表达式就可以组成组

using System;

using System.Text.RegularExpressions;

class chapter8

{

    static void Main()

    {

        string words = "08/14/57 46 02/25/59 45 06/05/85 18" + "03/12/88 16 09/09/90 13";

        string regExp1 = "(\\s\\d{2}\\s)";

        MatchCollection matchSet = Regex.Matches(words,regExp1);

        foreach (Match aMatch in matchSet)

            Console.WriteLine(aMatch.Groups[0].Captures[0]);

    }

}

 2 命名组

命名组通过在正则表达式前缀的问号和一对尖括号扩着的名字组成。

例如 "ages "中的组名

正则如下(?<ages>\\s\\d{2}\\s)

using System;

using System.Text.RegularExpressions;

class chapter8

{

    static void Main()

    {

        string words = "08/14/57 46 02/25/59 45 06/05/85 18 " + "03/12/88 16 09/09/90 13";

        string regExp1 = "(?<dates>(\\d{2}/\\d{2}/\\d{2}))\\s";

        MatchCollection matchSet = Regex.Matches(words,regExp1);

        foreach (Match aMatch in matchSet)

            Console.WriteLine("Date: {0}", aMatch.Groups["dates"]);

    }

}

 

 

零宽度正向预搜索断言和零宽度反向预搜索断言

断言还可以用来确定正则表达式向前或者向后匹配程度,这些断言可能是正( 匹配模式),也能是负的(非匹配模式)。

(?=reg-exp-char)

string words = "lions lion tigers tiger bears,bear";

string regExp1 = "\\w+(?=\\s)"; \\  只匹配当前子表达式在指定位置右侧,那么匹配就继续。

 

负的正向预搜索断言 ,只要搜索到不匹配的当前表达式的指定位置右侧,那么断言就继续。

string words = "subroutine routine subprocedure procedure";

string regExp1 = "\\b(?!sub)\\w+\\b";

 

反向预搜索断言

只要字表达式不匹配在位置左侧,那么负的反向与搜索断言就继续。

string words = "subroutines routine subprocedures

procedure";

string regExp1 = "\\b\\w+(?<=s)\\b";

 

 

string regExp1 = "\\b\\w+(?<!s)\\b";

 

 

CaptureCollection 类

using System;

using System.Text.RegularExpressions;

class chapter8

{

    static void Main()

    {

        string dates = "08/14/57 46 02/25/59 45 06/05/85 18 " + "03/12/88 16 09/09/90 13";

        string regExp = "(?<dates>(\\d{2}/\\d{2}/\\d{2}))\\s(?<ages>(\\d{2}))\\s";

        MatchCollection matchSet;

        matchSet = Regex.Matches(dates, regExp);

        Console.WriteLine();

        foreach (Match aMatch in matchSet)

        {

            foreach (Capture aCapture in aMatch.Groups["dates"].Captures)

                Console.WriteLine("date capture: " + aCapture.ToString());

            foreach (Capture aCapture in aMatch.Groups["ages"].Captures)

                Console.WriteLine("age capture: " + aCapture.ToString());

        }

    }

}

 

正则表达式选项

matchSet = Regex.Matches(dates, regexp, RegexOptions.Multiline);

posted @ 2012-02-11 20:15 超薄 阅读(30) 评论(0) 编辑
 
仅列出标题  下一页