• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            小四的海市蜃樓
            Never surrender to complexity
            posts - 21,comments - 59,trackbacks - 0
            幾天不寫程序手就有點生,整理了一段把圖片轉成ASCII碼的程序。暫時只支持24位真彩色圖片,ASCII碼可以自行擴充。大體算法就是把整個位圖分成8*16的小塊,計算小塊的灰度值總和,然后匹配一個灰度值接近的字符。具體算法細節可以參考網上資料。
            程序源代碼可以在這里下載。
             
            posted @ 2008-06-29 18:03 小四 閱讀(3969) | 評論 (11)編輯 收藏
            https://github.com/dingjiecn/OpenDraw.git

            打算做一個開源的矢量繪圖軟件(類似MS Visio),花了幾天把程序框架做了出來,自認比DrawCLI的稍微好一點點。支持基本圖形繪制,旋轉,縮放,串行化。使用MFC、STL、GDI/GDI+和一點點設計模式。

            自知做一個堪用的矢量繪圖軟件是個非常艱巨的事情,不過還是打算用一些業余時間把這件事情做了,對自己以往掌握的知識,也是一個總結。

            編譯好的可執行程序
            程序0.01版本源代碼在這里可以下載
            posted @ 2008-01-29 18:16 小四 閱讀(11670) | 評論 (37)編輯 收藏

            The barrier to change is not too little caring; it is too much complexity.

            To turn caring into action, we need to see a problem, see a solution, and see the impact. But complexity blocks all three steps.

            If we can really see a problem, which is the first step, we come to the second step: cutting through the complexity to find a solution.

            Cutting through complexity to find a solution runs through four predictable stages: determine a goal, find the highest-leverage approach, discover the ideal technology for that approach, and in the meantime, make the smartest application of the technology that you already have — whether it's something sophisticated, like a drug, or something simpler, like a bednet.

            The final step – after seeing the problem and finding an approach – is to measure the impact of your work and share your successes and failures so that others learn from your efforts.

            But if you want to inspire people to participate, you have to show more than numbers; you have to convey the human impact of the work – so people can feel what saving a life means to the families affected.

             

            posted @ 2008-01-15 10:04 小四 閱讀(346) | 評論 (0)編輯 收藏

            GDI+的顏色矩陣由一個5*5的float型數組構成,用來對每一個像素的顏色(R,G,B,A)做線性變換,每個像素顏色與矩陣相乘。把一幅彩色圖轉成灰度圖的算法是,假設像素點顏色為(r,g,b),轉換成灰度圖三個顏色分量是一樣的,稱作灰階,灰階的計算是 r*0.299+g*0.587+b*0.114。我們可以逐個像素轉換,也可以使用顏色矩陣。所以彩色圖轉灰度圖的顏色矩陣為
            ColorMatrix matrix =
            {0.299, 0.299, 0.299, 0, 0,
             0.587, 0.587, 0.587, 0, 0,
             0.114, 0.114, 0.114, 0, 0,
             0,     0,     0,     1, 0,
             0,     0,     0,     0, 0}

            這樣轉換后,灰度圖的灰階分布在0~255之間。如果想把一幅彩色圖渲染成雙色圖,定義一個深顏色darker,一個淺顏色lighter,那么灰度圖只是一個darker是黑色而lighter是白色的特例。本來分布在0~255的灰階,這樣應該分別分布在(lighter.r~darker.r),(lighter.g~darker.g),(lighter.b~darker.b)。

            編寫代碼如下,使用白色和紫色。

            void CDuotoneDlg::OnButton1() 
            {
                Bitmap  img(L
            "c:\\test1.jpg");
                Graphics graphix(
            this->GetDC()->m_hDC);

                Color darker(
            0);
                Color lighter(
            8414370);

                
            const float gray_r = 0.299f;
                
            const float gray_g = 0.587f;
                
            const float gray_b = 0.114f;

                
            float offset_r = (float)darker.GetR() / 255;
                
            float offset_g = (float)darker.GetG() / 255;
                
            float offset_b = (float)darker.GetB() / 255;    

                
            float r = (float)(lighter.GetR() - darker.GetR()) / 255;
                
            float g = (float)(lighter.GetG() - darker.GetG()) / 255;
                
            float b = (float)(lighter.GetB() - darker.GetB()) / 255;

                ImageAttributes imgatt;
                ColorMatrix matrix 
            =
                    
            {
                       gray_r
            *r, gray_r*g, gray_r*b, 00,
                       gray_g
            *r, gray_g*g, gray_g*b, 00,
                       gray_b
            *r, gray_b*g, gray_b*b, 00,
                       
            00010
                       offset_r, offset_g, offset_b, 
            01
                    }
            ;

                imgatt.SetColorMatrix(
            &matrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap);

                
            int iWidth = img.GetWidth();
                
            int iHeight = img.GetHeight();

                graphix.DrawImage(
                    
            &img,
                    Rect(
            00, iWidth, iHeight),  
                    
            0.0f,                         
                    
            0.0f,                         
                    iWidth,                       
                    iHeight,                      
                    UnitPixel,
                    
            &imgatt);

                graphix.ReleaseHDC(
            this->GetDC()->m_hDC);
            }

            渲染圖片測試
            posted @ 2008-01-05 14:01 小四 閱讀(652) | 評論 (0)編輯 收藏
                 摘要: 表達式求值的關鍵點在于中綴表達式轉后綴表達式,算法書上都有明確介紹就不多說了。動手實現了一個表達式解析器,支持括號、多位整數以及表達式合法性判斷。今天的狀態實在很差,本想對表達式進行合法性判斷的時候使用一些類似哈希表的技巧,比如使用一個大的bool數組,合法字符ASC碼對應的項設置為1,比如可以直接判斷CHARS['+']是否為true,省去查找的時間。后來發現一共就支持那幾個字符,這樣做未免有點...  閱讀全文
            posted @ 2008-01-04 19:59 小四 閱讀(697) | 評論 (0)編輯 收藏

            二叉排序樹,又稱二叉查找樹,左子樹結點值一律小于父結點,右子樹結點值一律大于父結點,查找平均算法復雜度為O(logn)。
            還是那道統計單詞數目的題目,使用二叉排序樹來解決,查找和插入以及統計數目使用一個函數解決,比使用哈希表的優勢在于,中序遍歷輸出結果,單詞是有序的。

            程序中需要注意的地方,釋放樹結點的時候,要使用后續遍歷,先釋放子結點后才釋放根結點。

            /* -------------------------------------------------------------------------
            // 文件名  : binarytree.h
            // 創建者  :  dj
            // 創建時間 : 2008-1-1
            // 功能描述 : 二叉排序樹
            // -----------------------------------------------------------------------
            */

            #ifndef __BINARYTREE_H__
            #define __BINARYTREE_H__

            #define SAFE_DELETE(p) {if(p) { delete [] (p); (p) = NULL;}}

            struct TreeNode
            {
                TreeNode(
            const char* s):
                counter(
            1), left(NULL), right(NULL)
                
            {
                    name 
            = new char[strlen(s)+1];
                    strcpy(name, s);
                }

                
            ~TreeNode()
                
            {
                    SAFE_DELETE(name);
                }

                
            char* name;
                
            int counter;
                TreeNode
            * left;
                TreeNode
            * right;
            }
            ;

            class BinaryTree
            {

            public:
                BinaryTree():m_pRoot(NULL)
                
            {}
                
            ~BinaryTree()
                
            {
                    FreeTree(m_pRoot);
                }

                
            void Lookup(const char* sName)
                
            {
                    TreeNode
            ** p = &m_pRoot;
                    
            while(*p)
                    
            {
                        
            int cmp = strcmp(sName, (*p)->name);
                        
            if (cmp<0)
                            p 
            = &((*p)->left);
                        
            else if (cmp>0)
                            p 
            = &((*p)->right);
                        
            else                        //found the word
                        {
                            ((
            *p)->counter)++;        //increase the counter
                            return;
                        }

                    }

                    
            // not found,  then add the word node.
                    TreeNode* pNode = new TreeNode(sName);
                    
            *= pNode;
                }

                
            void Dump(const char* sFile)
                
            {
                    ofstream f(sFile);
                    Travel(m_pRoot, f);
                    f.close();
                }

            private:
                
            void Travel(TreeNode* pNode, ofstream& f)
                
            {
                    
            if (!pNode)
                        
            return;
                    Travel(pNode
            ->left, f);
                    f
            <<pNode->name<<"  "<<pNode->counter<<endl;
                    Travel(pNode
            ->right, f);
                }

                
            void FreeTree(TreeNode* pNode)
                
            {
                    
            if(!pNode)
                        
            return;
                    FreeTree(pNode
            ->left);
                    FreeTree(pNode
            ->right);
                    delete pNode;        
                }

            private:
                TreeNode
            * m_pRoot;
            }
            ;

            #endif //__BINARYTREE_H__

            int main(int argc, char* argv[])
            {
                BinaryTree tree;
                ifstream f(
            "c:\\ip.txt");
                
            string s;
                
            while(f>>s)
                
            {
                    tree.Lookup(s.c_str());
                }

                tree.Dump(
            "c:\\stat.txt");
                
            return 0;
            }
            posted @ 2008-01-01 21:49 小四 閱讀(418) | 評論 (0)編輯 收藏
            折半查找又叫二分查找,要求查找表本身必須是有序的。查找算法復雜度為O(logn)。C標準庫提供折半查找的庫函數,聲明如下
            bsearch(const void *, const void *, size_t, size_t, int (__cdecl *)(const void *, const void *));
            最后一個參數要求一個指向比較函數的指針。程序設計實踐上寫道,為bsearch提供一個key就這么費勁,寫一個好的通用的排序程序也不容易,即使這樣,使用bsearch而不是自己另外寫仍然是個好主意。
            多年的歷史證明,程序員能把二分檢索程序寫正確也是很不容易的(Over the years, binary search has proven surprisingly hard for programmer to get right)。

            于是自己用模板寫一個折半查找函數,寫好一個十幾行的程序,也不是看上去那么簡單的事情。
            template<typename T>
            int binarysearch(const T* tab, int ntab, const T& value)
            {
                
            int low = 0;
                
            int high = ntab;
                
            while(low <= high)
                
            {
                    
            int mid = (low+high)/2;
                    
            if(value<tab[mid])
                        high 
            = mid - 1;
                    
            else if (value>tab[mid])
                        low 
            = mid + 1;
                    
            else
                        
            return mid;
                }

                
            return -1;
            }

            測試程序
            int main(int argc, char* argv[])
            {
                
            int a[] = {24678913};
                
            int aa = sizeof(a);
                
            int n = binarysearch(a, sizeof(a)/sizeof(a[0]), 4);
                cout
            <<n<<endl;
                
            return 0;
            }

            posted @ 2008-01-01 17:59 小四 閱讀(1072) | 評論 (0)編輯 收藏
                 摘要: 寫了一個哈希表模板類,用于統計一篇文章中不同單詞出現的次數。哈希表使用char*作為key,使用桶式鏈表指針數組(指向結點鏈表的指針數組)來索引,字符串哈希函數是在網上搜來的。模板參數一個是值類型,另一個NBARREL是指針數組的大小,通常是越大哈希值沖突就越少,結點鏈表長度也就越短,當然查找就越快。 為了方便統計,為哈希表增加了一個IncValue函數,提高效率。統計的時候使用了快速排序,為了...  閱讀全文
            posted @ 2007-12-30 15:13 小四 閱讀(544) | 評論 (0)編輯 收藏

            在程序設計實踐上看到這個簡單的快速排序,用模板重新寫了一遍,加深一下印象。平均算法復雜度為O(nlogn)。

            其中尋找支點元素pivot有多種方法,不同的方法會導致快速排序的不同性能。根據分治法平衡子問題的思想,希望支點元素可以使p[m..n]盡量平均地分為兩部分,但實際上很難做到。下面給出幾種尋找pivot的方法。

            1.選擇p[m..n]的第一個元素p[m]的值作為pivot;
            2.選擇p[m..n]的最后一個元素p[n]的值作為pivot;
            3.選擇p[m..n]中間位置的元素p[k]的值作為pivot;
            4.選擇p[m..n]的某一個隨機位置上的值p[random(n-m)+m]的值作為pivot;
              按照第4種方法隨機選擇pivot的快速排序法又稱隨機化版本的快速排序法,在實際應用中該方法的性能也是最好的。本程序使用第4種方法。要求節點類型支持比較運算符。


            template<typename T>
            void quicksort(T* v, int n)
            {
                
            if (n<=1)
                    
            return;
                
            int last = 0;
                
            int pivot = rand()%n;
                swap(v, 
            0, pivot);
                
            for (int i = 1; i < n; i++)
                
            {
                    
            if (v[i]<v[0])
                        swap(v, 
            ++last, i);
                }

                swap(v, last, 
            0);
                quicksort(v, last);
                quicksort(v
            +last+1, n-last-1);
            }


            template
            <typename T>
            void swap(T* v, int i, int j)
            {
                T tmp 
            = v[i];
                v[i] 
            = v[j];
                v[j] 
            = tmp;    
            }


            隨手寫一個不太好看的測試程序

            struct str
            {
                str(
            const char* a)
                
            {
                    assert(a);
                    v 
            = new char[strlen(a)+1];
                    strcpy(v, a);
                }

                str(
            const str& a)
                
            {
                    assert(a.v);
                    v 
            = new char[strlen(a.v)+1];
                    strcpy(v, a.v);
                }

                
            ~str()
                
            {
                    delete [] v;
                }

                
            void operator = (const str& a)
                
            {
                    
            if (this == &a)
                        
            return;
                    assert(a.v);
                    delete [] v;
                    v 
            = new char[strlen(a.v)+1];
                    strcpy(v, a.v);
                }

                
            bool operator == (const str& a) const
                
            {
                    
            return (strcmp(v, a.v)==0);
                }

                
            bool operator > (const str& a) const 
                
            {
                    
            return (strcmp(v, a.v)>0);
                }

                
            bool operator < (const str& a) const
                
            {
                    
            return (strcmp(v, a.v)<0);
                }

                
            char* v;
            }
            ;


            int main(int argc, char* argv[])
            {
                
            int* array = new int [10];
                
            for(int i = 0; i < 10; i++)
                    array[i] 
            = rand();
                quicksort(array, 
            10);
                
            for(i = 0; i < 10; i++)
                
            {
                    cout
            <<array[i]<<endl;
                }


                str s[] 
            = {"bd""e""ba""a"};
                quicksort(s, 
            4);
                
            for(i = 0; i < 4; i++)
                
            {
                    cout
            <<s[i].v<<endl;
                }

                
            return 0;
            }


            posted @ 2007-12-29 14:31 小四 閱讀(405) | 評論 (0)編輯 收藏

            復習一下數據結構,用鏈表實現了一個堆棧模板類。
            寫的過程中用到一些知識點,碰到一些問題,隨手記下來。

            1:mystack<int> s; mystack<int> s2 = s;
            編譯器會把s2 = s編譯成拷貝構造函數s2(s),此時調用的是拷貝構造函數,而不是賦值函數(切記)。
            另外有時候編譯器這種自做聰明,自動調用符合參數類型的構造函數會帶來很難發現的錯誤,為了防止編譯器這么做,可以在構造函數聲明前加explicit關鍵字。

            2:不改變成員變量值的函數,例如empty(),要聲明為const,這點很重要,不然當一個const mystack&類型的對象調用empty()的時候,會編不過。

            3:拷貝構造函數最好要先判斷是否是拷貝自身,不然有時候就出錯。

            4:拷貝構造函數也別忘了成員變量初始化列表。 

            template<typename T>
            class mystack
            {
            public:
                mystack();
                mystack(
            const mystack& src);
                
            ~mystack();
                
            bool push(const T& data);
                T pop();
                
            bool empty() const;
                
            void clear();
                mystack
            & operator = (const mystack& src);
            private:
                
            void copystack(mystack& dst, const mystack& src);
                
            struct stacknode
                
            {
                    T data;
                    stacknode
            * pnext;
                }
            ;
                stacknode
            * phead;
            }
            ;

            template
            <typename T>
            mystack
            <T>::mystack():phead(NULL)
            {}

            template
            <typename T>
            mystack
            <T>::mystack(const mystack<T>& src):
            phead(NULL)
            {
                copystack(
            *this, src);
            }


            template
            <typename T>
            mystack
            <T>::~mystack()
            {
                clear();
            }


            template
            <typename T>
            void mystack<T>::clear()
            {
                
            while(!empty())
                
            {
                    
            pop();
                }

            }


            template
            <typename T>
            void mystack<T>::copystack(mystack& dst, const mystack& src)
            {
                stacknode
            * p = src.phead;
                mystack
            <T> tmp;
                
            while(p)
                
            {
                    tmp.push(p
            ->data);
                    p 
            = p->pnext;
                }

                
            while(!tmp.empty())
                
            {
                    dst.push(tmp.pop());
                }

            }


            template
            <typename T>
            mystack
            <T>& mystack<T>::operator=(const mystack& src)
            {
                
            if (this == &src)
                    
            return *this;
                clear();
                copystack(
            *this, src);
                
            return *this;
            }


            template
            <typename T>
            bool mystack<T>::empty() const 
            {
                
            return(phead == NULL);
            }


            template
            <typename T>
            bool mystack<T>::push(const T& data)
            {
                stacknode
            * p = new stacknode;
                
            if (!p) return false;
                p
            ->data = data;
                p
            ->pnext = phead;
                phead 
            = p;
                
            return true;
            }


            template
            <typename T>
            T mystack
            <T>::pop()
            {
                assert(
            !empty());
                T data;
                data 
            = phead->data;
                stacknode
            * tmp = phead;
                phead 
            = phead->pnext;
                delete tmp;
                
            return data;
            }


            int main(int argc, char* argv[])
            {
                mystack
            <int> s;    
                
            for (int i = 0; i < 1000; i++)
                    s.push(rand());
                mystack
            <int> s2(s);
                
            while(!s2.empty())
                
            {
                    cout
            <<s2.pop()<<endl;
                }

                
            return 0;
            }
            posted @ 2007-12-27 13:15 小四 閱讀(376) | 評論 (1)編輯 收藏
            僅列出標題
            共3頁: 1 2 3 
            久久永久免费人妻精品下载| 亚洲国产精品综合久久网络| 久久久亚洲裙底偷窥综合| 久久久久久久97| 久久国产精品成人影院| 久久精品国产一区二区三区日韩| 精品乱码久久久久久夜夜嗨| AV无码久久久久不卡蜜桃| 久久亚洲中文字幕精品有坂深雪| 久久久久久精品成人免费图片| 久久国产免费观看精品3| 99久久精品国产毛片| 精品国产乱码久久久久久人妻| 色妞色综合久久夜夜| 精品国产热久久久福利| 2019久久久高清456| 久久青草国产精品一区| 超级碰碰碰碰97久久久久| 久久不射电影网| 亚洲综合伊人久久大杳蕉| 久久er国产精品免费观看8| 亚洲精品午夜国产VA久久成人| 精品久久久久一区二区三区| 久久99国产综合精品女同| 中文字幕久久亚洲一区| 久久久精品视频免费观看| 99久久精品午夜一区二区 | 国产亚洲欧美成人久久片| 亚洲精品无码久久毛片| 久久精品这里只有精99品| 久久福利青草精品资源站免费| 久久人人爽人人爽人人片AV东京热| 久久综合丁香激情久久| 精品永久久福利一区二区| 久久SE精品一区二区| 久久精品一区二区三区AV| 亚洲精品无码久久毛片| 亚洲精品午夜国产va久久| 久久久久99精品成人片三人毛片| 国产精品久久久久久久久久免费| 国产一区二区三区久久精品|