Thursday, January 31, 2013
a very good example of iterative refinement of brute-force solution
string search: given two strings s and t, find all occurrences of s in t. since s can occur at any offset in t. the brutal force solution is to test for a match at every offset.
1. accelerate:
matching backwards.
2. a partial match does not result in full match implies other offsets which cannot lead to full matches.
data structure introduction:
min_heap
1. accelerate:
matching backwards.
2. a partial match does not result in full match implies other offsets which cannot lead to full matches.
data structure introduction:
min_heap
Use
make_heap()
and friends, defined in <algorithm>
, or use priority_queue
, defined in<queue>
. The priority_queue
uses make_heap
and friends underneath.#include <queue> // functional,iostream,ctime,cstdlib
using namespace std;
int main(int argc, char* argv[])
{
srand(time(0));
priority_queue<int,vector<int>,greater<int> > q;
for( int i = 0; i != 10; ++i ) q.push(rand()%10);
cout << "Min-heap, popped one by one: ";
while( ! q.empty() ) {
cout << q.top() << ' '; // 0 3 3 3 4 5 5 6 8 9
q.pop();
}
cout << endl;
return 0;
}
Heap just guarantees that elements on higher levels are greater (for max-heap) or smaller (for min-heap) than elements on lower levels, whereas BST guarantees order (from "left" to "right"). If you want sorted elements, go with BST.
some tree operations
<recursion is most common, but there is memory call overhead>
inorder: stack
preorder: dfs
postorder: stack
stl replacement of tree:
set and map
inorder: stack
preorder: dfs
postorder: stack
nonRecursivePostorder(rootNode)
nodeStack.push(rootNode)
while (! nodeStack.empty())
currNode = nodeStack.peek()
if ((currNode.left != null) and (currNode.left.visited == false))
nodeStack.push(currNode.left)
else
if ((currNode.right != null) and (currNode.right.visited == false))
nodeStack.push(currNode.right)
else
print currNode.value
currNode.visited := true
nodeStack.pop()
stl replacement of tree:
set and map
struct ltstr { bool operator()(const char* s1, const char* s2) const { return strcmp(s1, s2) < 0; } }; int main() { const int N = 6; const char* a[N] = {"isomer", "ephemeral", "prosaic", "nugatory", "artichoke", "serif"}; const char* b[N] = {"flat", "this", "artichoke", "frigate", "prosaic", "isomer"}; set<const char*, ltstr> A(a, a + N); set<const char*, ltstr> B(b, b + N); set<const char*, ltstr> C; cout << "Set A: "; copy(A.begin(), A.end(), ostream_iterator<const char*>(cout, " ")); cout << endl; cout << "Set B: "; copy(B.begin(), B.end(), ostream_iterator<const char*>(cout, " ")); cout << endl; cout << "Union: "; set_union(A.begin(), A.end(), B.begin(), B.end(), ostream_iterator<const char*>(cout, " "), ltstr()); cout << endl; cout << "Intersection: "; set_intersection(A.begin(), A.end(), B.begin(), B.end(), ostream_iterator<const char*>(cout, " "), ltstr()); cout << endl; set_difference(A.begin(), A.end(), B.begin(), B.end(), inserter(C, C.begin()), ltstr()); cout << "Set C (difference of A and B): "; copy(C.begin(), C.end(), ostream_iterator<const char*>(cout, " ")); cout << endl; }
Tuesday, January 29, 2013
bit operator in good use
and &,or |, XOR ^
0xFF=(0x==hex) FF=255
0xFF-1=0xFE
go to cracking the coding interview 95..
~0
0xFF=(0x==hex) FF=255
0xFF-1=0xFE
go to cracking the coding interview 95..
~0
hash_map in stl
Hash_map is a
Hashed Associative Container
that associates objects of type Key with
objects of type Data. Hash_map is a
Pair Associative Container,
meaning that its value type is
pair<const Key, Data>. It is also a
Unique Associative Container,
meaning that no two elements have keys that compare
equal using EqualKey.
Looking up an element in a hash_map by its key is efficient, so hash_map is useful for "dictionaries" where the order of elements is irrelevant. If it is important for the elements to be in a particular order, however, then map is more appropriate.
Looking up an element in a hash_map by its key is efficient, so hash_map is useful for "dictionaries" where the order of elements is irrelevant. If it is important for the elements to be in a particular order, however, then map is more appropriate.
Example
struct eqstr { bool operator()(const char* s1, const char* s2) const { return strcmp(s1, s2) == 0; } }; int main() { hash_map<const char*, int, hash<const char*>, eqstr> months; months["january"] = 31; months["february"] = 28; months["march"] = 31; months["april"] = 30; months["may"] = 31; months["june"] = 30; months["july"] = 31; months["august"] = 31; months["september"] = 30; months["october"] = 31; months["november"] = 30; months["december"] = 31; cout << "september -> " << months["september"] << endl; cout << "april -> " << months["april"] << endl; cout << "june -> " << months["june"] << endl; cout << "november -> " << months["november"] << endl; }
my experience is that it is important to use hash_map whenever necessary!
Friday, January 25, 2013
malloc memcpy
1 struct Test {
2 char * ptr;
3 };
4 void shallow_copy(Test & src, Test & dest) {
5 dest.ptr = src.ptr;
6 }
7 void deep_copy(Test & src, Test & dest) {
8 dest.ptr = malloc(strlen(src.ptr) + 1);
9 memcpy(dest.ptr, src.ptr);
10 }
volatile and mutex
mutable:
This keyword can only be applied to non-static and non-const data members of a class. If a data member is declared mutable, then it is legal to assign a value to this data member from a const member function.
mutable member-variable-declaration;
For example, the following code will compile without error because m_accessCount has been declared to be mutable, and therefore can be modified by GetFlag even though GetFlag is a const member function.
// mutable.cpp class X { public: bool GetFlag() const { m_accessCount++; return m_flag; } private: bool m_flag; mutable int m_accessCount; }; int main() { }
how is std::map implemented
So it can be used to quickly implement a red-black tree!
In an STL map, insertion of key/value pair is in sorted order of key. It uses a tree to store values, which is why an O(log N) insert/lookup is required. There is also no need to handle collisions. An STL map works well for things like:
»»find min element
»»find max element
»»print elements in sorted order
»»find the exact element or, if the element is not found, find the next smallest number
example:
#include<map>
#include<string>
#include<iostream>
using namespace std;
int main()
{
map<string,int> p;
p["jan"]=1;
p["feb"]=2;
cout<<p["feb"]<<p["mar"]<<endl;
system("pause");
}
map is implemented using red-black tree.
Probably the two most common self balancing tree algorithms are Red-Black trees and AVL trees. To balance the tree after an insertion/update both algorithms use the notion of rotations where the nodes of the tree are rotated to perform the re-balancing.
While in both algorithms the insert/delete operations are O(log n), in the case of Red-Black tree re-balancing rotation is an O(1) operation while with AVL this is a O(log n) operation, making the Red-Black tree more efficient in this aspect of the re-balancing stage and one of the possible reasons that it is more commonly used.
Red-Black trees are used in most collection libraries, including the offerings from Java and Microsoft .NET Framework.
using namespace std; typedef std::map<int,int> MAP; typedef std::pair<int,int> PAIR; int main() { MAP squares_map; squares_map.insert( PAIR(2,4) ); squares_map.insert( PAIR(0,0) ); squares_map.insert( PAIR(1,1) ); squares_map.insert( PAIR(6,36) ); squares_map.insert( PAIR(3,9) ); if (!squares_map.empty()) { MAP::iterator it_min = squares_map.begin(); MAP::iterator it_max = squares_map.end(); // points to just past last element --it_max; // points to last element cout << "min element : " << it_min->first << " " << it_min->second << "\n"; cout << "max element : " << it_max->first << " " << it_max->second << "\n"; } return 0; }
Labels:
AVL tree,
C++,
data structure,
map,
red-black tree,
stl
VPTR
class MBase
{
public:
void f() const {};
~MBase(){}
};
if you try to check the size of this class, you can write something like:
MBase base;
cout<<sizeof(base);
OK the size is one byte. But upon changing it to virtual functions, the size of increase to four bytes. Check it out here:
http://www.cprogramming.com/tutorial/size_of_class_object.html
how i solved the problem of matlab char16_t redefinition
it was super easy.
open the file c:\program files\matlab\r2010a\extern\include\matrix.h
and comment out "typedef CHAR16_T char16_t
#ifndef __STDC_UTF_16__
# ifndef CHAR16_T
# if defined(_WIN32) && defined(_MSC_VER)
# define CHAR16_T wchar_t
# else
# define CHAR16_T UINT16_T
# endif
// typedef CHAR16_T char16_t; //brutal force. but works fine for me
# endif
#endif
open the file c:\program files\matlab\r2010a\extern\include\matrix.h
and comment out "typedef CHAR16_T char16_t
#ifndef __STDC_UTF_16__
# ifndef CHAR16_T
# if defined(_WIN32) && defined(_MSC_VER)
# define CHAR16_T wchar_t
# else
# define CHAR16_T UINT16_T
# endif
// typedef CHAR16_T char16_t; //brutal force. but works fine for me
# endif
#endif
Subscribe to:
Posts (Atom)