锘??xml version="1.0" encoding="utf-8" standalone="yes"?> k榪戦偦錛坘 nearest neighbor錛夌畻娉曟槸涓縐嶇洃鐫g畻娉曪紝鐢ㄤ簬鍒嗙被銆傚畠鍩烘湰鎬濇兂鏄綆楁柊瀹炰緥鍜岃緇冮泦鍏冪礌鐨?*璺濈**錛屾壘鍑簁涓渶鎺ヨ繎鐨勫疄渚嬶紙neighbor錛夛紝緇熻瀹冧滑鎵灞炲垎綾伙紝嬈℃暟鏈澶氱殑綾誨埆浣滀負鏂板疄渚嬬殑綾誨埆銆?
鐩戠潱綆楁硶鍙ぇ鑷村垎鎴愪袱涓楠わ細璁粌錛坱rain錛夊拰鍒嗙被錛坈lassify錛夈備粠瀹炵幇鑰冭檻榪橀渶瑕佺畻娉曞垵濮嬪寲榪囩▼銆?
鏈妭鐨勪唬鐮佷負python椋庢牸鐨勭ず鎰忎唬鐮侊紝涓嶈兘鐩存帴榪愯錛屽彲榪愯浠g爜鍙傝儂xml銆?
紺烘剰浠g爜
聽
]]>鍘熺悊涓庢楠?
class KNearestNeighbor:
def __init__(...): pass
def train(...): pass
def classify(...): pass
鐞嗚涓妅榪戦偦綆楁硶涓嶉渶瑕佽緇冿紝鍙洿鎺ヤ嬌鐢ㄥ師濮嬫暟鎹繘琛屽垎綾匯?
褰掍竴鍖?/strong>
鏁版嵁鐨勫垎綾葷殑閲忕翰宸埆杈冨ぇ鏃訛紝灝忛噺綰插垎綾誨湪璁$畻鐨勬潈閲嶅皢琚墛寮便備嬌鐢ㄥ綊涓鍖栨秷闄よ繖縐嶅獎鍝嶃傛柟娉曞涓嬶細
x虃鈥?鈥?x鈥呪垝鈥?em>xmin)/(xmax鈥呪垝鈥?em>xmin)
棰勫鐞?/strong>
灝嗘暟鎹繘琛屾煇縐嶅艦寮忕殑澶勭悊鍙姞蹇鎵緆榪戦偦鐨勯熷害錛屽父鐢ㄧ殑澶勭悊鏂瑰紡鏈塊D-Tree鍜孊all-Tree錛屽墠鑰呭浣庣淮嬈ф皬璺濈鏈夋晥錛屽悗鑰呭鎵鏈夎窛紱繪湁鏁堛?
紺烘剰浠g爜
聽
def train(self, X, C):
'''X,C鍒嗗埆浠h〃瀹炰緥鍜岀被鍒?''
聽
# 瀹炰緥鏁版嵁褰掍竴鍖栵紝騫朵繚鐣欐暟鎹浠?
(self.X, self.C) = (normalize(X), C.copy())
聽
# 鍙夛紝濡傛灉闇瑕侊紝鍒欐瀯寤篕D-Tree()
self.tree = KDTree()
self.tree.create(self.X)
鍒嗙被鐨勫ぇ鑷存楠わ細鎵懼嚭k涓繎閭?/em> 鍜?緇熻綾誨埆鐨勬鏁? 銆?鍒嗙被鐨勯儴鍒嗗鐞嗕笌璁粌鐨勫鐞嗗悜瀵瑰簲錛屽錛?
紺烘剰浠g爜
聽
def classify(self, x):
聽
_x = normalize(x) # 灝唜褰掍竴鍖?
nearest = self.find_neighbors(_x) # 鎵懼嚭k涓繎閭?
freq = frequency(nearests) # 緇熻姣忎釜綾誨瀷鐨勬鏁?
return freq.sorted()[-1] # 鎺掑簭鍚庯紝榪斿洖嬈℃暟鏈澶氱殑綾誨埆
聽
def find_neighbors(self, x):
'''瀵繪壘涓巟鏈鎺ヨ繎鐨刱涓偣'''
聽
if self.tree == None: # 鍒ゆ柇鏄惁浣跨敤浜唊d-tree
ds = self.distance(x, self.X) # 璁$畻鎵鏈夌偣鐨勮窛紱?
indices = ds.argsort()[0:k] # 鎺掑簭鍚庯紝鍙栧墠闈涓?
聽
else:
indices = self.tree.find_neighbors(x, self.k)
聽
# indices鏄痥涓繎閭葷殑绱㈠紩浣嶇疆
return self.C[indices]
鍒濆鍖栭渶瑕佽緗畻娉曞弬鏁幫紝濡俴鐨勫鹼紝璺濈鍏紡銆?
璺濈
瀹炰緥涔嬮棿鐨勮窛紱諱竴鑸噰鐢ㄦ姘忚窛紱伙紝浣嗕笉鎺掗櫎浣跨敤鍏跺畠鐨勮窛紱昏綆楁柟娉曘傛姘忚窛紱伙細
d鈥?鈥?/span>鈭?/span>x鈥呪垝鈥?em>y鈭?/span>鈥?鈥?span style="font-size:18pt">鈭?/span>(鈭?/span>(xi鈥呪垝鈥?em>yi)2)鈥呪墺鈥?/span>鈭?/span>xi鈥呪垝鈥?em>yi鈭?/span>
聽
def __init__(self, k, distance=euclidean ):
(self.k, self.distance) = (k, distance)
涓嬮潰浣跨敤scikit-learn涓殑k榪戦偦綆楁硶鍒嗙被鐨勪緥瀛愩?
聽
import numpy as np
from sklearn import neighbors
聽
# 鍑嗗鏁版嵁錛屽垎鎴怉 B涓ょ被銆侫綾誨湪[0,0]闄勮繎錛孊綾誨湪[1,1]闄勮繎銆?
X = np.array([[0, 0.1], [-0.1, 0],
[0.1, 0.1], [0, 0],
[1, 1], [1.1, 1],
[1, 1.1], [1.1, 1.1]])
聽
C = ['A','A','A','A','B','B','B','B']
聽
# 鍒濆鍖?
clf = neighbors.KNeighborsClassifier(n_neighbors=3, weights="uniform")
聽
# 璁粌
clf.fit(X, C)
聽
# 鍒嗙被
c = clf.predict(np.array([[0.9,0.8]]))
print(c)
涓婇潰鐨勪緥瀛愬彲浠ュ皢k榪戦偦綆楁硶鍒嗘垚涓夋錛屽垵濮嬪寲銆佽緇冨拰鍒嗙被銆傚垵濮嬪寲鍙緗弬鏁幫紝鏈枃娑夊強鍒扮殑鍙傛暟鏈夛細
綾葷殑鏋勯犲嚱鏁版姏鍑哄紓甯革紝涓嶄細璋冪敤璇ョ被鐨勬瀽鏋勫嚱鏁幫紝璧勬簮鐨勯噴鏀懼師鍒欐槸緙栬瘧鍣ㄧ敵璇風殑緙栬瘧鍣ㄨ礋璐o紝紼嬪簭鍛樼敵璇風殑紼嬪簭鍛樿礋璐c?
鍦ㄥ疄楠屼唬鐮佷腑錛屽瓙綾籈xcept鐨勬瀯閫犲嚱鏁版姏鍑哄紓甯革紝鍒橞ase鍜宮Member1鐨勬瀯閫犲嚱鏁版槸緙栬瘧鍣ㄨ皟鐢紝鍥犳緙栬瘧鍣ㄤ細璋冪敤瀹冧滑鐨勬瀽鏋勫嚱鏁幫紝鑰宮Member2鐢辯▼搴忓憳涓誨姩浣跨敤new鐢熸垚錛屽洜姝ら渶瑕佺▼搴忓憳涓誨姩浣跨敤delete銆?/p>
瑙e喅鏂規硶錛?/p>
try...catch
緇撴瀯
/**
* @file constructor_exception.cpp
* @brief 嫻嬭瘯鏋勯犲嚱鏁板紓甯稿紩璧風殑琛屼負
* @copyright public domain
*/
#include <iostream>
#include <exception>
#include <memory>
class Base {
public:
Base() { std::cout << "Base()" << std::endl; }
virtual ~Base() { std::cout << "~Base()" << std::endl; }
};
class Member {
public:
Member(int id):mId(id) { std::cout << "Member():" << mId << std::endl; }
virtual ~Member() { std::cout << "~Member()" << mId << std::endl; }
protected:
int mId;
};
class Except : public Base {
public:
Except() : mMember1(1), mMember2(NULL) {
std::cout << "Except() enter" << std::endl;
mMember2 = new Member(2);
mMember3.reset(new Member(3));
throw std::exception();
std::cout << "Except() leave" << std::endl;
}
virtual ~Except() {
delete mMember2;
std::cout << "~Except()" << std::endl;
}
protected:
Member mMember1;
Member *mMember2;
std::auto_ptr<Member> mMember3;
};
int main() {
try {
Except e;
} catch (std::exception& e) {
std::cout << e.what() << std::endl;
}
return 0;
}
$ g++ constructor_exception.cpp
$ ./a.out
Base()
Member():1
Except() enter
Member():2
Member():3
~Member()3
~Member()1
~Base()
std::exception
鏋勯犲嚱鏁扮殑璋冪敤欏哄簭鏄厛鐖剁被鍐嶅瓙綾匯傛瀽鏋勫嚱鏁扮殑欏哄簭鐩稿弽鈥斺斿厛瀛愮被鍐嶇埗綾匯傛湁緇ф壙鍏崇郴鐨勭被鐨勬瀽鏋勫嚱鏁伴渶瑕佸0鏄庝負virtual錛屼絾騫墮潪蹇呴』銆傚0鏄巚irtual琛ㄦ槑鍑芥暟涓嶈兘鍐嶇紪璇戞湡闂寸‘瀹氾紝鍙湁鍦ㄨ繍琛屾椂鎵嶈兘紜畾銆傝繖鏍風殑鍦烘櫙鏄垹闄ゅ熀綾繪寚閽堬紝浣嗗叾鎸囧悜鏄淳鐢熺被銆傛鏃剁紪璇戝櫒鐪嬪埌鐨勫彧鏈夊熀綾諱俊鎭紝濡傛灉娌℃湁澹版槑virtual錛屽氨娌℃湁铏氬嚱鏁拌〃鎴栬呰櫄鍑芥暟琛ㄦ病鏈夋瀽鏋勫嚱鏁伴」錛屽彧鑳借皟鐢ㄥ熀綾葷殑鏋愭瀯鍑芥暟銆傚鏋滀笉澹版槑virtual錛屽皢瀛愮被鎸囬拡璧嬪肩粰鐖剁被鎸囬拡鏄湁椋庨櫓鐨勬搷浣溿?/p>
## 瀹為獙浠g爜
```C
/**
* @file constructor_destructor_sequence.cpp
* @brief 嫻嬭瘯鏋勯犳瀽鏋勫嚱鏁扮殑璋冪敤嬈″簭
* @copyright public domain
*/
#include <iostream>
class Base {
public:
Base() { std::cout << "Base()" << std::endl; }
~Base() { std::cout << "~Base()" << std::endl; }
};
class VBase {
public:
VBase() { std::cout << "VBase()" << std::endl; }
virtual ~VBase() { std::cout << "~VBase()" << std::endl; }
};
class Derived : public Base {
public:
Derived() { std::cout << "Derived()" << std::endl; }
~Derived() { std::cout << "~Derived()" << std::endl; }
};
class VDerived: public VBase {
public:
Derived() { std::cout << "VDerived()" << std::endl; }
~VDerived() { std::cout << "~VDerived()" << std::endl; }
};
void test_0() {
std::cout <<"瀛愮被涓嶅0鏄巚irtual錛屾寜鍩虹被鎸囬拡鍒犻櫎媧劇敓綾? << std::endl;
VBase* p = new VDerived;
delete p;
}
void test_1() {
std::cout <<"涓嶅0鏄巚irtual錛屾寜媧劇敓綾繪寚閽堝垹闄ゆ淳鐢熺被" << std::endl;
Derived* p = new Derived;
delete p;
}
void test_2() {
std::cout <<"涓嶅0鏄巚irtual錛屾寜鍩虹被鎸囬拡鍒犻櫎媧劇敓綾? << std::endl;
Base* p = new Derived;
delete p;
}
void test_3() {
std::cout <<"涓嶅0鏄巚irtual錛屾寜void*鍒犻櫎媧劇敓綾? << std::endl;
void* p = new Derived;
delete p;
}
int main() {
test_0();
test_1();
test_2();
test_3();
return 0;
}
```
## 榪愯鍙婄粨鏋?br>
> g++ constructor_destructor_sequence.cpp
constructor_destructor_sequence.cpp: In function 'void test_3()':
constructor_destructor_sequence.cpp:54:9: warning: deleting 'void*' is undefined [enabled by default]
> a.exe
瀛愮被涓嶅0鏄巚irtual錛屾寜鍩虹被鎸囬拡鍒犻櫎媧劇敓綾?/p>
VBase()
VDerived()
~VDerived()
~VBase()
涓嶅0鏄巚irtual錛屾寜媧劇敓綾繪寚閽堝垹闄ゆ淳鐢熺被
Base()
Derived()
~Derived()
~Base()
涓嶅0鏄巚irtual錛屾寜鍩虹被鎸囬拡鍒犻櫎媧劇敓綾?/p>
Base()
Derived()
~Base()
涓嶅0鏄巚irtual錛屾寜void*鍒犻櫎媧劇敓綾?/p>
Base()
Derived()
浣跨敤char[]
鍜?code>char*瀹氫箟鍙橀噺錛屽茍璧嬪煎瓧絎︿覆甯擱噺錛岃繖涓よ呮湁杈冨ぇ鍖哄埆銆傚墠鑰呭畾涔夋暟緇勶紝騫跺皢瀛楃涓插父閲忔嫹璐濊嚦璇ユ暟緇勶紝鍙橀噺琛ㄧず榪欎釜鏂版暟緇勭殑棣栧湴鍧銆傚悗鑰呭畾涔夋寚閽堬紝鎸囧悜涓涓瓧絎﹀父閲忋傚墠鑰呬細浜х敓鏂扮殑瀛楃涓叉暟鎹紝騫朵笖鎷ユ湁璇誨啓鏉冮檺錛屽悗鑰呬笉涓瀹氫駭鐢熸柊瀛楃涓叉暟鎹紝騫朵笖鍙湁璇繪潈闄愩?/p>
/**
* @file char_array_pointer.cpp
* @brief 嫻嬭瘯瀛楃鏁扮粍鍜屾寚閽?/span>
* @copyrigh public domain
*/
#include <iostream>
const char* string0() {
const char* str = "string";
return str;
}
const char* string1() {
return "string";
}
const char* string2() {
static const char str[] = "string";
return str;
}
const char* string3() {
char str[] = "string";
return str;
}
void function() {
char a[] = "abc123456";
}
void test_string1() {
const char* str = string1();
std::cout << "test_string1: " << str << std::endl;
function();
std::cout << "test_string1: " << str << std::endl;
}
void test_string2() {
const char* str = string2();
std::cout << "test_string2: " << str << std::endl;
function();
std::cout << "test_string2: " << str << std::endl;
}
void test_string3() {
const char* str = string3();
std::cout << "test_string3: " << str << std::endl;
function();
std::cout << "test_string3: " << str << std::endl;
}
int main() {
std::cout << "string0 == string1 is " << (string0() == string1() ? "true" : "false") << std::endl;
std::cout << "string1 == string2 is " << (string1() == string2() ? "true" : "false") << std::endl;
test_string1();
test_string2();
test_string3();
return 0;
}
$ g++ char_array_pointer.cpp
char_array_pointer.cpp: In function 'const char* string3()':
char_array_pointer.cpp:24:10: warning: address of local variable 'str' returned [enabled by default]
$ ./a.exe
string0 == string1 is true
string1 == string2 is false
test_string1: string
test_string1: string
test_string2: string
test_string2: string
test_string3: string
test_string3: abc12345YP@
瀛楃涓插父閲忎細鏀懼叆紼嬪簭鐨勯潤鎬佸尯錛屽茍涓旀槸鍙鏁版嵁孌點傜敱浜庢槸鍙鏁版嵁錛岀紪璇戝櫒浼氬悎騫剁浉鍚岀殑瀛楃涓插父閲忋?/p>
/**
* @file constant_string.cpp
* @brief 嫻嬭瘯甯擱噺瀛楃涓?/span>
* @copyright public domain
*/
#include <iostream>
int main() {
char* a = "string";
const char* b = "string";
std::cout << "a == b is " << (a==b ? "true" : "false") << std::endl;
a[1] = 'd'; // ERROR
return 0;
}
$ g++ constant_string.cpp
constant_string.cpp: In function 鈥榠nt main()鈥?
constant_string.cpp:10:12: warning: deprecated conversion from string constant to 鈥榗har*鈥?[-Wwrite-strings]
char* a = "string";
^
$ ./a.out
a == b is true
孌甸敊璇?(鏍稿績宸茶漿鍌?
a
鍜?code>b鐨勫湴鍧鐩稿悓銆?/li>
big endian鍜宭ittle endian琛ㄧず濡備綍瀛樻斁澶氬瓧鑺傛暟鎹傚墠鑰呬綆浣嶅瓧鑺傛帓鏀懼湪鍐呭瓨鐨勯珮绔紝鍚庤呯浉鍙嶃傚皢unsigned long鏁版嵁寮哄埗杞崲鎴恥nsigned char*鏁版嵁錛屽垯瀹冧滑鍦ㄤ袱縐嶆ā寮忎笅鐨勫搴斿叧緋誨涓嬶細
big endian錛?/p>
ul = (uc[0]<< 24) + (uc[1]<<16) + (uc[2]<<8) + uc[3];
little endian:
ul = (uc[3]<<24) + (uc[2]<<16) + (uc[1]<<8) + uc[0];
/**
* @file little_big_endian.cpp
* @brief 嫻嬭瘯澶у皬绔瓧鑺傚簭
* @copyright public domain
*/
#include <iostream>
static bool is_little_endian() {
union {
long l;
char cs[4];
} t;
t.l = 1;
return t.cs[0] == 1;
}
int main() {
unsigned long ul = 0x12345678;
unsigned char* uc = (unsigned char*)&ul;
if (is_little_endian()) {
bool r = (uc[0] + (uc[1]<<8) + (uc[2]<<16) + (uc[3]<<24)) == ul;
std::cout << "little: (uc[0] + (uc[1]<<8) + (uc[2]<<16) + (uc[3]<<24)) == ul is " << (r ? "true" : "false") << std::endl;
} else {
bool r = (uc[3] + (uc[2]<<8) + (uc[1]<<16) + (uc[0]<<24)) == ul;
std::cout << "little: (uc[3] + (uc[2]<<8) + (uc[1]<<16) + (uc[0]<<24)) == ul is " << (r ? "true" : "false") << std::endl;
}
return 0;
}
$ g++ little_big_endian.cpp
$ ./a.out
little: (uc[0] + (uc[1]<<8) + (uc[2]<<16) + (uc[3]<<24)) == ul is true
瀛楄妭搴忕殑闂瀹規槗鍑虹幇鍦ㄤ笉鍚岀數鑴戜氦浜掓暟鎹殑鏃跺欙紝鍥犳褰撴暟鎹緭鍑烘椂鈥斺斾繚瀛樻垚鏂囦歡鎴栧湪緗戠粶涓婁紶杈撯斺斿氨搴旇鑰冭檻瀛楄妭搴忋?/p>
C++綾繪垚鍛樺垵濮嬪寲欏哄簭鍙栧喅浜庡叾澹版槑欏哄簭錛岃岄潪鍒濆鍖栧垪琛ㄧ殑欏哄簭銆?/p>
/**
* 嫻嬭瘯綾繪垚鍛樼殑鍒濆鍖栭『搴?/span>
* @file init_oder.cpp
*/
#include <iostream>
class Test {
public:
Test() : mBb(sIndex++), mAa(sIndex++) { }
public:
void Dump() {
std::cout<< "a: " << mAa << ", b: " << mBb << std::endl;
}
protected:
int mAa;
int mBb;
static int sIndex;
};
int Test::sIndex = 1;
int main() {
Test t;
t.Dump();
return 0;
}
$ g++ init_order.cpp
$ ./a.out
a: 1, b: 2
褰撶被鐨勬垚鍛樺垵濮嬪寲鏈変緷璧栧叧緋伙紙濡傛煇涓垚鍛樼殑鏋勯犲嚱鏁扮殑鍙傛暟鏄彟涓涓垚鍛橈級鏃訛紝杈冨鏄撳嚭閿欍傝繖鏄洜涓虹▼搴忓憳鐨勬剰鍥撅紙鍒濆鍖栧垪琛ㄩ『搴忥級鍜岀▼搴忕殑琛屼負錛堟垚鍛樺0鏄?欏哄簭錛夋槸鍒嗙鐨勶紝鍓嶈呬竴鑸綅浜庡疄鐜版枃浠訛紝鍚庤呬綅浜庡ご鏂囦歡錛岀紪杈戝墠鑰呭線寰蹇界暐鍚庤呫傚洜姝ゅ皯鐢ㄦ湁渚濊禆鐨勫垵濮嬪寲璁捐錛屽茍涓斿湪review涓姞鍏ヨ媯鏌ユ潯鐩?/p>
/**
* @file empty_size.cpp
* @brief 嫻嬭瘯絀虹被鐨勫ぇ灝?/span>
* @copyright public domain
*/
#include<iostream>
class Empty { };
class SubEmpty : public Empty
{
protected:
int mInt;
};
class VEmpty
{
public:
virtual ~VEmpty() = 0;
};
int main()
{
std::cout << "Empty class: " << sizeof(Empty) << std::endl;
std::cout << "SubEmpty: " << sizeof(SubEmpty) << std::endl;
std::cout << "VEmpty: " << sizeof(VEmpty) << std::endl;
std::cout << "Void*: " << sizeof(void*) << std::endl;
return 0;
};
> g++ empty_size.cpp
> a.exe
Empty class: 1
SubEmpty: 4
VEmpty: 8
Void*: 8