Go语言实现HashSet
set.go
// set project set.go
package set type Set interface {
Add(e interface{}) bool
Remove(e interface{})
Clear()
Contains(e interface{}) bool
Len() int
Same(other Set) bool
Elements() []interface{}
String() string
} // 将集合other添加到集合one中
func AddSet(one Set, other Set) {
if one == nil || other == nil || other.Len() == {
return
}
for _, v := range other.Elements() {
one.Add(v)
}
} // 判断集合 one 是否是集合 other 的超集
func IsSuperset(one Set, other Set) bool {
if one == nil || other == nil {
return false
}
oneLen := one.Len()
otherLen := other.Len()
if oneLen == || oneLen <= otherLen {
return false
}
if oneLen > && otherLen == {
return true
}
for _, v := range other.Elements() {
if !one.Contains(v) {
return false
}
}
return true
} // 生成集合 one 和集合 other 的并集
func Union(one Set, other Set) Set {
if one == nil && other == nil {
return nil
}
unionedSet := NewSimpleSet()
AddSet(unionedSet, one)
AddSet(unionedSet, other)
return unionedSet
} // 生成集合 one 和集合 other 的交集
func Intersect(one Set, other Set) Set {
if one == nil || other == nil {
return nil
}
intersectedSet := NewSimpleSet()
if one.Len() == || other.Len() == {
return intersectedSet
}
if one.Len() < other.Len() {
for _, v := range one.Elements() {
if other.Contains(v) {
intersectedSet.Add(v)
}
}
} else {
for _, v := range other.Elements() {
if one.Contains(v) {
intersectedSet.Add(v)
}
}
}
return intersectedSet
} // 生成集合 one 对集合 other 的差集
func Difference(one Set, other Set) Set {
if one == nil {
return nil
}
differencedSet := NewSimpleSet()
if other == nil || other.Len() == {
AddSet(differencedSet, one)
return differencedSet
}
for _, v := range one.Elements() {
if !other.Contains(v) {
differencedSet.Add(v)
}
}
return differencedSet
} // 生成集合 one 和集合 other 的对称差集
func SymmetricDifference(one Set, other Set) Set {
diffA := Difference(one, other)
if other == nil || other.Len() == {
return diffA
}
diffB := Difference(other, one)
return Union(diffA, diffB)
} // 返回一个HashSet
func NewSimpleSet() Set {
return NewHashSet()
} // 判断给定value是否为集合
func IsSet(value interface{}) bool {
if _, ok := value.(Set); ok {
return true
}
return false
}
hash_set.go
// hash_set
package set import (
"bytes"
"fmt"
) type HashSet struct {
m map[interface{}]bool
} // 创建和初始化HashSet的方法
func NewHashSet() *HashSet {
return &HashSet{m: make(map[interface{}]bool)}
} // 向HashSet中添加元素的方法
func (set *HashSet) Add(e interface{}) bool {
if !set.m[e] {
set.m[e] = true
return true
}
return false
} // 删除HashSet中指定的元素
func (set *HashSet) Remove(e interface{}) {
delete(set.m, e)
} // 清除HashSet中的所有元素
func (set *HashSet) Clear() {
set.m = make(map[interface{}]bool)
} // 判断HashSet是否包含指定元素
func (set *HashSet) Contains(e interface{}) bool {
return set.m[e]
} // 获取HashSet中元素值数量
func (set *HashSet) Len() int {
return len(set.m)
} // 判断两个Set类型值是否相同
func (set *HashSet) Same(other Set) bool {
if other == nil {
return false
}
if set.Len() != other.Len() {
return false
}
for key := range set.m {
if !other.Contains(key) {
return false
}
}
return true
} // 生成HashSet的一个快照
func (set *HashSet) Elements() []interface{} {
initialLen := len(set.m)
snapshot := make([]interface{}, initialLen)
actualLen :=
for key := range set.m {
if actualLen < initialLen {
snapshot[actualLen] = key
} else {
snapshot = append(snapshot, key)
}
actualLen++
}
if actualLen < initialLen {
snapshot = snapshot[:actualLen]
}
return snapshot
} // 获取HashSet自身字符串表示形式
func (set *HashSet) String() string {
var buf bytes.Buffer
buf.WriteString("Set{")
first := true
for key := range set.m {
if first {
first = false
} else {
buf.WriteString(" ")
}
buf.WriteString(fmt.Sprintf("%v", key))
}
buf.WriteString("}")
return buf.String()
}
功能测试:
set_test.go
// set_test
package set import (
"bytes"
"fmt"
"math/rand"
"runtime/debug"
"strings"
"testing"
"time"
) func testSetLenAndContains(t *testing.T, newSet func() Set, typeName string) {
t.Logf("Starting Test%sLenAndContains...", typeName)
set, expectedElemMap := genRandSet(newSet)
t.Logf("Got a %s value: %v.", typeName, set)
expectedLen := len(expectedElemMap)
if set.Len() != expectedLen {
t.Errorf("ERROR: The length of %s value %d is not %d!\n",
set.Len(), typeName, expectedLen)
t.FailNow()
}
t.Logf("The length of %s value is %d.\n", typeName, set.Len())
for k := range expectedElemMap {
if !set.Contains(k) {
t.Errorf("ERROR: The %s value %v do not contains %v!",
set, typeName, k)
t.FailNow()
}
}
} func testSetAdd(t *testing.T, newSet func() Set, typeName string) {
t.Logf("Starting Test%sAdd...", typeName)
set := newSet()
var randElem interface{}
var result bool
expectedElemMap := make(map[interface{}]bool)
for i := ; i < ; i++ {
randElem = genRandElement()
t.Logf("Add %v to the %s value %v.\n", randElem, typeName, set)
result = set.Add(randElem)
if expectedElemMap[randElem] && result {
t.Errorf("ERROR: The element adding (%v => %v) is successful but should be failing!\n",
randElem, set)
t.FailNow()
}
if !expectedElemMap[randElem] && !result {
t.Errorf("ERROR: The element adding (%v => %v) is failing!\n",
randElem, set)
t.FailNow()
}
expectedElemMap[randElem] = true
}
t.Logf("The %s value: %v.", typeName, set)
expectedLen := len(expectedElemMap)
if set.Len() != expectedLen {
t.Errorf("ERROR: The length of %s value %d is not %d!\n",
set.Len(), typeName, expectedLen)
t.FailNow()
}
t.Logf("The length of %s value is %d.\n", typeName, set.Len())
for k := range expectedElemMap {
if !set.Contains(k) {
t.Errorf("ERROR: The %s value %v do not contains %v!",
set, typeName, k)
t.FailNow()
}
}
} func testSetRemove(t *testing.T, newSet func() Set, typeName string) {
t.Logf("Starting Test%sRemove...", typeName)
set, expectedElemMap := genRandSet(newSet)
t.Logf("Got a %s value: %v.", typeName, set)
t.Logf("The length of %s value is %d.\n", typeName, set.Len())
var number int
for k, _ := range expectedElemMap {
if number% == {
t.Logf("Remove %v from the HashSet value %v.\n", k, set)
set.Remove(k)
if set.Contains(k) {
t.Errorf("ERROR: The element removing (%v => %v) is failing!\n",
k, set)
t.FailNow()
}
delete(expectedElemMap, k)
}
number++
}
expectedLen := len(expectedElemMap)
if set.Len() != expectedLen {
t.Errorf("ERROR: The length of HashSet value %d is not %d!\n", set.Len(), expectedLen)
t.FailNow()
}
t.Logf("The length of %s value is %d.\n", typeName, set.Len())
for _, v := range set.Elements() {
if !expectedElemMap[v] {
t.Errorf("ERROR: The HashSet value %v contains %v but should not contains!", set, v)
t.FailNow()
}
}
} func testSetClear(t *testing.T, newSet func() Set, typeName string) {
t.Logf("Starting Test%sClear...", typeName)
set, _ := genRandSet(newSet)
t.Logf("Got a %s value: %v.", typeName, set)
t.Logf("The length of %s value is %d.\n", typeName, set.Len())
t.Logf("Clear the HashSet value %v.\n", set)
set.Clear()
expectedLen :=
if set.Len() != expectedLen {
t.Errorf("ERROR: The length of HashSet value %d is not %d!\n", set.Len(), expectedLen)
t.FailNow()
}
t.Logf("The length of %s value is %d.\n", typeName, set.Len())
} func testSetElements(t *testing.T, newSet func() Set, typeName string) {
t.Logf("Starting Test%sElements...", typeName)
set, expectedElemMap := genRandSet(newSet)
t.Logf("Got a %s value: %v.", typeName, set)
t.Logf("The length of %s value is %d.\n", typeName, set.Len())
elems := set.Elements()
t.Logf("The elements of %s value is %v.\n", typeName, elems)
expectedLen := len(expectedElemMap)
if len(elems) != expectedLen {
t.Errorf("ERROR: The length of HashSet value %d is not %d!\n", len(elems), expectedLen)
t.FailNow()
}
t.Logf("The length of elements is %d.\n", len(elems))
for _, v := range elems {
if !expectedElemMap[v] {
t.Errorf("ERROR: The elements %v contains %v but should not contains!", set, v)
t.FailNow()
}
}
} func testSetSame(t *testing.T, newSet func() Set, typeName string) {
t.Logf("Starting Test%sSame...", typeName)
set, _ := genRandSet(newSet)
t.Logf("Got a %s value: %v.", typeName, set)
t.Logf("The length of %s value is %d.\n", typeName, set.Len())
set2 := newSet()
t.Logf("Clone the HashSet value %v...\n", set)
for _, v := range set.Elements() {
set2.Add(v)
}
result := set2.Same(set)
if !result {
t.Errorf("ERROR: Two sets are not same!")
}
t.Logf("Two sets are same.")
} func testSetString(t *testing.T, newSet func() Set, typeName string) {
t.Logf("Starting Test%sString...", typeName)
set, _ := genRandSet(newSet)
t.Logf("Got a %s value: %v.", typeName, set)
setStr := set.String()
t.Logf("The string of %s value is %s.\n", typeName, setStr)
var elemStr string
for _, v := range set.Elements() {
elemStr = fmt.Sprintf("%v", v)
if !strings.Contains(setStr, elemStr) {
t.Errorf("ERROR: The string of %s value %s do not contains %s!",
typeName, setStr, elemStr)
t.FailNow()
}
}
} // ----- Set 公用函数测试 ----- func TestIsSuperset(t *testing.T) {
defer func() {
if err := recover(); err != nil {
debug.PrintStack()
t.Errorf("Fatal Error: %s\n", err)
}
}()
t.Log("Starting TestIsSuperset...")
set, _ := genRandSet(func() Set { return NewSimpleSet() })
set2 := NewSimpleSet()
for _, v := range set.Elements() {
set2.Add(v)
}
for extraElem := genRandElement(); ; {
if set2.Add(extraElem) {
break
} else {
time.Sleep( * time.Millisecond)
}
}
if !IsSuperset(set2, set) {
t.Errorf("ERROR: The HashSet value %v is not a superset of %v!\n", set2, set)
t.FailNow()
} else {
t.Logf("The HashSet value %v is a superset of %v.\n", set2, set)
}
for extraElem := genRandElement(); ; {
if set.Add(extraElem) {
break
} else {
time.Sleep( * time.Millisecond)
}
}
if IsSuperset(set2, set) {
t.Errorf("ERROR: The HashSet value %v should not be a superset of %v!\n", set2, set)
t.FailNow()
} else {
t.Logf("The HashSet value %v is not a superset of %v.\n", set2, set)
}
} func TestUnion(t *testing.T) {
defer func() {
if err := recover(); err != nil {
debug.PrintStack()
t.Errorf("Fatal Error: %s\n", err)
}
}()
t.Log("Starting TestUnion...")
set, _ := genRandSet(func() Set { return NewSimpleSet() })
t.Logf("The set value: %v", set)
set2, _ := genRandSet(func() Set { return NewSimpleSet() })
uSet := Union(set, set2)
t.Logf("The set value (2): %v", set2)
for _, v := range set.Elements() {
if !uSet.Contains(v) {
t.Errorf("ERROR: The union set value %v do not contains %v!",
uSet, v)
t.FailNow()
}
}
for _, v := range set2.Elements() {
if !uSet.Contains(v) {
t.Errorf("ERROR: The union set value %v do not contains %v!",
uSet, v)
t.FailNow()
}
}
t.Logf("The set value %v is a unioned set of %v and %v", uSet, set, set2)
} func TestIntersect(t *testing.T) {
defer func() {
if err := recover(); err != nil {
debug.PrintStack()
t.Errorf("Fatal Error: %s\n", err)
}
}()
t.Log("Starting TestIntersect...")
commonElem := genRandElement()
set, _ := genRandSet(func() Set { return NewSimpleSet() })
set.Add(commonElem)
t.Logf("The set value: %v", set)
set2, _ := genRandSet(func() Set { return NewSimpleSet() })
set2.Add(commonElem)
t.Logf("The set value (2): %v", set2)
iSet := Intersect(set, set2)
for _, v := range iSet.Elements() {
if !set.Contains(v) {
t.Errorf("ERROR: The set value %v do not contains %v!",
set, v)
t.FailNow()
}
if !set2.Contains(v) {
t.Errorf("ERROR: The set value %v do not contains %v!",
set2, v)
t.FailNow()
}
}
t.Logf("The set value %v is a intersected set of %v and %v", iSet, set, set2)
} func TestDifference(t *testing.T) {
defer func() {
if err := recover(); err != nil {
debug.PrintStack()
t.Errorf("Fatal Error: %s\n", err)
}
}()
t.Log("Starting TestDifference...")
commonElem := genRandElement()
set, _ := genRandSet(func() Set { return NewSimpleSet() })
set.Add(commonElem)
t.Logf("The set value: %v", set)
set2, _ := genRandSet(func() Set { return NewSimpleSet() })
set2.Add(commonElem)
t.Logf("The set value (2): %v", set2)
dSet := Difference(set, set2)
for _, v := range dSet.Elements() {
if !set.Contains(v) {
t.Errorf("ERROR: The set value %v do not contains %v!",
set, v)
t.FailNow()
}
if set2.Contains(v) {
t.Errorf("ERROR: The set value %v contains %v!",
set2, v)
t.FailNow()
}
}
t.Logf("The set value %v is a differenced set of %v to %v", dSet, set, set2)
} func TestSymmetricDifference(t *testing.T) {
defer func() {
if err := recover(); err != nil {
debug.PrintStack()
t.Errorf("Fatal Error: %s\n", err)
}
}()
t.Log("Starting TestSymmetricDifference...")
commonElem := genRandElement()
set, _ := genRandSet(func() Set { return NewSimpleSet() })
set.Add(commonElem)
t.Logf("The set value: %v", set)
set2, _ := genRandSet(func() Set { return NewSimpleSet() })
set2.Add(commonElem)
t.Logf("The set value (2): %v", set2)
sdSet := SymmetricDifference(set, set2)
for _, v := range sdSet.Elements() {
if set.Contains(v) && set2.Contains(v) {
t.Errorf("ERROR: The element %v can not be a common element of %v to %v!",
v, set, set2)
t.FailNow()
}
}
t.Logf("The set value %v is a symmetric differenced set of %v to %v", sdSet, set, set2)
} // ----- 随机测试对象生成函数 ----- func genRandSet(newSet func() Set) (set Set, elemMap map[interface{}]bool) {
set = newSet()
elemMap = make(map[interface{}]bool)
var enough bool
for !enough {
e := genRandElement()
set.Add(e)
elemMap[e] = true
if len(elemMap) >= {
enough = true
}
}
return
} func genRandElement() interface{} {
seed := rand.Int63n()
switch seed {
case :
return genRandInt()
case :
return genRandString()
case :
return struct {
num int64
str string
}{genRandInt(), genRandString()}
default:
const length =
arr := new([length]interface{})
for i := ; i < length; i++ {
if i% == {
arr[i] = genRandInt()
} else {
arr[i] = genRandString()
}
}
return *arr
}
} func genRandString() string {
var buff bytes.Buffer
var prev string
var curr string
for i := ; buff.Len() < ; i++ {
curr = string(genRandAZAscii())
if curr == prev {
continue
} else {
prev = curr
}
buff.WriteString(curr)
}
return buff.String()
} func genRandAZAscii() int {
min := // A
max := // Z
rand.Seed(time.Now().UnixNano())
return min + rand.Intn(max-min)
} func genRandInt() int64 {
return rand.Int63n()
}
hash_set_test.go
// hash_set_test
package set import (
"fmt"
"runtime/debug"
"strings"
"testing"
) func TestHashSetCreation(t *testing.T) {
defer func() {
if err := recover(); err != nil {
debug.PrintStack()
t.Errorf("Fatal Error: %s\n", err)
}
}()
t.Log("Starting TestHashSetCreation...")
hs := NewHashSet()
t.Logf("Create a HashSet value: %v\n", hs)
if hs == nil {
t.Errorf("The result of func NewHashSet is nil!\n")
}
isSet := IsSet(hs)
if !isSet {
t.Errorf("The value of HashSet is not Set!\n")
} else {
t.Logf("The HashSet value is a Set.\n")
}
} func TestHashSetLenAndContains(t *testing.T) {
testSetLenAndContains(t, func() Set { return NewHashSet() }, "HashSet")
} func TestHashSetAdd(t *testing.T) {
testSetAdd(t, func() Set { return NewHashSet() }, "HashSet")
} func TestHashSetRemove(t *testing.T) {
testSetRemove(t, func() Set { return NewHashSet() }, "HashSet")
} func TestHashSetClear(t *testing.T) {
testSetClear(t, func() Set { return NewHashSet() }, "HashSet")
} func TestHashSetElements(t *testing.T) {
testSetElements(t, func() Set { return NewHashSet() }, "HashSet")
} func TestHashSetSame(t *testing.T) {
testSetSame(t, func() Set { return NewHashSet() }, "HashSet")
} func TestSetString(t *testing.T) {
testSetString(t, func() Set { return NewHashSet() }, "HashSet")
} func testSetOp(t *testing.T) {
defer func() {
if err := recover(); err != nil {
debug.PrintStack()
t.Errorf("Fatal Error: %s\n", err)
}
}()
fmt.Println()
t.Logf("Starting TestHashSetOp...")
hs := NewHashSet()
if hs.Len() != {
t.Errorf("ERROR: The length of original HashSet value is not 0!\n")
t.FailNow()
}
randElem := genRandElement()
expectedElemMap := make(map[interface{}]bool)
t.Logf("Add %v to the HashSet value %v.\n", randElem, hs)
hs.Add(randElem)
expectedElemMap[randElem] = true
expectedLen := len(expectedElemMap)
if hs.Len() != expectedLen {
t.Errorf("ERROR: The length of HashSet value %d is not %d!\n", hs.Len(), expectedLen)
t.FailNow()
}
var result bool
for i := ; i < ; i++ {
randElem = genRandElement()
t.Logf("Add %v to the HashSet value %v.\n", randElem, hs)
result = hs.Add(randElem)
if expectedElemMap[randElem] && result {
t.Errorf("ERROR: The element adding (%v => %v) is successful but should be failing!\n",
randElem, hs)
t.FailNow()
}
if !expectedElemMap[randElem] && !result {
t.Errorf("ERROR: The element adding (%v => %v) is failing!\n",
randElem, hs)
t.FailNow()
}
expectedElemMap[randElem] = true
}
expectedLen = len(expectedElemMap)
if hs.Len() != expectedLen {
t.Errorf("ERROR: The length of HashSet value %d is not %d!\n", hs.Len(), expectedLen)
t.FailNow()
}
for k, _ := range expectedElemMap {
if !hs.Contains(k) {
t.Errorf("ERROR: The HashSet value %v do not contains %v!", hs, k)
t.FailNow()
}
}
number :=
for k, _ := range expectedElemMap {
if number% == {
t.Logf("Remove %v from the HashSet value %v.\n", k, hs)
hs.Remove(k)
if hs.Contains(k) {
t.Errorf("ERROR: The element adding (%v => %v) is failing!\n",
randElem, hs)
t.FailNow()
}
delete(expectedElemMap, k)
}
number++
}
expectedLen = len(expectedElemMap)
if hs.Len() != expectedLen {
t.Errorf("ERROR: The length of HashSet value %d is not %d!\n", hs.Len(), expectedLen)
t.FailNow()
}
for _, v := range hs.Elements() {
if !expectedElemMap[v] {
t.Errorf("ERROR: The HashSet value %v contains %v!", hs, v)
t.FailNow()
}
}
hs2 := NewHashSet()
for k, _ := range expectedElemMap {
hs2.Add(k)
}
if !hs.Same(hs2) {
t.Errorf("ERROR: HashSet value %v do not same %v!\n", hs, hs2)
t.FailNow()
}
str := hs.String()
t.Logf("The string of HashSet value %v is '%s'.\n", hs, str)
for _, v := range hs.Elements() {
if !strings.Contains(str, fmt.Sprintf("%v", v)) {
t.Errorf("ERROR: '%s' do not contains '%v'!", str, v)
t.FailNow()
}
}
}
Go语言实现HashSet的更多相关文章
- Go目录
1. Go语言获取项目当前路径 2. Go语言TCP/UDP Socket编程 3. Go语言实现HashSet
- Haskell语言学习笔记(77)Data.HashSet
安装 unordered-containers $ cabal install unordered-containers Installed unordered-containers-0.2.9.0 ...
- [Java语言] HashMap,HashSet,Hashtable,Vector,ArrayList 的关系 <转>
这么几个比较常用的但是比较容易混淆的概念同出于 java.util 包.本文仅作几个类的浅度解析. (本文基于JDK1.7,源码来自openjdk1.7.) ├── Collection │ ├── ...
- 学Android开发,入门语言java知识点
学Android开发,入门语言java知识点 Android是一种以Linux为基础的开源码操作系统,主要使用于便携设备,而linux是用c语言和少量汇编语言写成的,如果你想研究Android,就去学 ...
- Spring表达式语言 之 5.3 SpEL语法(拾肆)
5.3 SpEL语法 5.3.1 基本表达式 一.字面量表达式: SpEL支持的字面量包括:字符串.数字类型(int.long.float.double).布尔类型.null类型. 类型 示例 字 ...
- Apache Thrift - 可伸缩的跨语言服务开发框架
To put it simply, Apache Thrift is a binary communication protocol 原文地址:http://www.ibm.com/developer ...
- 微软在 .NET 3.5 新增了一个 HashSet 类,在 .NET 4 新增了一个 SortedSet 类,本文介绍他们的特性,并比较他们的异同。
微软在 .NET 3.5 新增了一个 HashSet 类,在 .NET 4 新增了一个 SortedSet 类,本文介绍他们的特性,并比较他们的异同. .NET Collection 函数库的 Has ...
- 【原创】关于hashcode和equals的不同实现对HashMap和HashSet集合类的影响的探究
这篇文章做了一个很好的测试:http://blog.csdn.net/afgasdg/article/details/6889383,判断往HashSet(不允许元素重复)里塞对象时,是如何判定set ...
- 笔记整理——C语言-http-1
http 传输原理及格式 - friping - ITeye技术网站 - Google Chrome (2013/4/1 14:02:36) http 传输原理及格式 博客分类: 其他 应用服务器浏览 ...
随机推荐
- 访问IIS元数据库失败解决方法
问题:访问元数据失败 详细信息 访问 IIS 元数据库失败. 说明: 执行当前 Web 请求期间,出现未处理的异常.请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息. 异常详细信 ...
- 浅谈压缩感知(三十一):压缩感知重构算法之定点连续法FPC
主要内容: FPC的算法流程 FPC的MATLAB实现 一维信号的实验与结果 基于凸优化的重构算法 基于凸优化的压缩感知重构算法. 约束的凸优化问题: 去约束的凸优化问题: 在压缩感知中,J函数和H函 ...
- paip.php 与js 的相似性以及为什么它们这么烂还很流行。。
paip.php 与js 的相似性以及为什么它们这么烂还很流行.. php与js异常的流行,web 90%都被他们统治了.发现了他们有意思的一些共性.. 结构一番总结,得出了它们共有的特点.特性: = ...
- Javascript设置广告和时间表和数组的学习
<html> <head> <meta charset="utf-8"> <title></title> </he ...
- CSS实现特殊效果
CSS实现三道杠效果 http://jsbin.com/hocopusuvi/edit?html,css,output CSS实现圆点效果 http://jsbin.com/nojiromaje/ed ...
- 运行(WIN+R)中能使用的命令:ms-settings:,shell:,cpl,mmc...
ms-settings: --- DESC --- --- CMD --- Battery Saver ms-settings:batterysaver Battery Saver Settings ...
- Prototype in JavaScript
声明 本文旨在入门,简单了解下何为prototype & __proto__ 原型对象 我们创建每个函数都有个prototype(原型)属性,该属性是一个指针,指向一个对象,而这对象的用途是包 ...
- iOS开发实用技巧—在手机浏览器头部弹出app应用下载提示
iOS开发实用技巧—在手机浏览器头部弹出app应用下载提示 本文介绍其简单使用: 第一步:在本地建立一个访问的服务端. 打开本地终端,在本地新建一个文件夹,在该文件夹中存放测试的html页面. ...
- android: SQLite查询数据
掌握了查询数据的方法之后,你也就将数据库的 CRUD 操 作全部学完了.不过千万不要因此而放松,因为查询数据也是在 CRUD 中最复杂的一种 操作. 我们都知道 SQL 的全称是 Structured ...
- Bilateral Filtering(双边滤波) for SSAO(转)
原文链接:http://blog.csdn.net/bugrunner/article/details/7170471 另外一篇相似的英文资料:http://homepages.inf.ed.ac.u ...