算法學習筆記(一)C++排序函數、映射技巧與字典樹

1.頭文件algorithm中有函數sort()用於排序,參數爲:排序起始地址,排序結束地址,排序規則(返回bool型)
例如,要將array[] = {5,7,1,2,9}升序排列,則使用:

bool cmp(int a,int b);
int main()
{
    int array[] = {5,7,1,2,9};
    sort(array,array+5,cmp);
    for(int i = 0;i < 5;i++)
        cout << array[i] << " ";
    cout << endl;
    return 0;
}

bool cmp(int a,int b)
{
    if(a>b) return false;
    else return true;
}

注:1.在C語言中,使用qsort進行排序。

    2.如果不指定排序方式,默認爲升序。



2.對於有序映射關係,可以用巧妙的辦法轉化,例如:

ABC對應2,DEF對應3,GHI對應4,JKL對應5,MNO對應6,PRS對應7,TUV對應8,WXY對應9

要把一串字符按照這樣的規則映射爲數字,可以採用以下方法:

(*(p+i) - 'A' - (*(p+i)>'Q'))/3 + 2

其中p爲指向字符串的指針,因爲每3個字母變化一次映射關係,因此只需要判斷當前字符距離字符A的距離,然後除以三判斷落在哪一組。需要注意的是字母Q不包含在映射關係當中,因此當字符在Q之後時,應該減去1個字符的距離再進行判斷。


3.字典樹是一種存放字符串的樹形結構,又稱爲單詞查找樹,利用的是字符串的公共前綴來減少查詢時間。需要注意的是字典樹常常用於統計單詞出現次數,而不是爲了取出單詞去存儲單詞。一般字典樹的結構體如下:

struct DirectionTree{
    int count;//計數到當前節點爲止的單詞個數
    bool terminal;//記錄此節點無子節點
    DirectionTree* child[26];//該節點的子節點
}*root;//字典樹的根節點,根節點不包含任何字母

字典樹的存放方式爲根連接子節點,子節點連接新的節點,一直連接到尾部。例如存儲字符"abc","ad",則數據結構如下:

wKiom1QeTZfwrCSjAAEA2r9xqMQ124.jpg

其中只有D3和D4兩個節點的terminal值爲true,count爲1,其餘的均爲false,0。當再次添加同樣的字符串時,不會創建新的節點,只會引起count加1。

完整代碼如下(轉):

#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <assert.h>
using namespace std;
#define MAX 26    //the total number of alphabet is 26, a...z

struct Dictree
{
    bool word;
    int count;
    struct Dictree *trie[MAX];    // the 26 child
} * a;

int init()        // init the chained list
{
    a = new Dictree;
    for(int i = 0; i < MAX; i++)
    {
        a->trie[i] = NULL;
        a->word = false;
    }

    return 0;
}

bool searchTrie(char *str)
{
    int len, res;
    Dictree *head = a;
    assert(head);
    len = strlen(str);

    for(int i = 0; i < len; i++)
    {
        res = (int)(str[i] - 'a');
        if(head->trie[res] == NULL)
            return false;
        head = head->trie[res];
    }

    if(head->word)
        return true;

    return false;
}

int insertTrie(char *str)
{
    int len, res;
    Dictree *head = a;
    len = strlen(str);

    for(int i = 0; i < len; i++)
    {
        res = int(str[i] - 'a');
        if(head->trie[res] == NULL)        //whether the node exist?
        {
            head->trie[res] = new Dictree;
            head = head->trie[res];
            head->count = 0;
            for(int j = 0; j < MAX; j++)
            {
                head->trie[j] = NULL;
                head->word = false;
            }
        }
        else
            head = head->trie[res];
    }
    head->count++;
    head->word = true;

    return head->count;
}

int main()
{
    char str[20];

    init();
    for(int i = 0; i < 10; i++)
    {
        scanf("%s", str);
        printf("%d\n", insertTrie(str));
    }

    scanf("%s", str);
    printf("%s\n", searchTrie(str) ? ("YES"):("NO"));

    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章