三、单词压缩存储
三、單詞壓縮存儲(chǔ)
文章目錄
- 三、單詞壓縮存儲(chǔ)
- 題目描述
- 解題思路
- 上機(jī)代碼
題目描述
如果采用單鏈表保存單詞,可采用如下辦法壓縮存儲(chǔ)空間。如果兩個(gè)單詞的后綴相同,則可以用同一個(gè)存儲(chǔ)空間保存相同的后綴。例如,原來(lái)分別采用單鏈表保存的單詞Str1“l(fā)oading”和單詞Str2“being”,經(jīng)過(guò)壓縮后的存儲(chǔ)形式如下。
請(qǐng)?jiān)O(shè)計(jì)一個(gè)高效的算法完成兩個(gè)單鏈表的壓縮存儲(chǔ)。
要求:閱讀預(yù)設(shè)代碼,編寫函數(shù)SNODE * ziplist( SNODE * head1, SNODE * head2 )
ziplist的功能是:在兩個(gè)串鏈表中,查找公共后綴,若有公共后綴,則壓縮 并返回指向公共后綴的指針;否則返回NULL。
說(shuō)明:本題目有預(yù)設(shè)代碼,只要提交你編寫的函數(shù)即可。
預(yù)設(shè)代碼:
/* PRESET CODE BEGIN - NEVER TOUCH CODE BELOW */#include <stdio.h> #include <stdlib.h>typedef struct sdata { char data;struct sdata *next; } SNODE;void setlink( SNODE *, char * ), outlink( SNODE * ); int listlen( SNODE * ); SNODE * ziplist( SNODE *, SNODE * ); SNODE * findlist( SNODE *, SNODE * );int main( ) { SNODE * head1, * head2, *head;char str1[100], str2[100];gets( str1 );gets( str2 );head1 = (SNODE *) malloc( sizeof(SNODE) );head2 = (SNODE *) malloc( sizeof(SNODE) );head = (SNODE *) malloc( sizeof(SNODE) );head->next = head1->next = head2->next = NULL;setlink( head1, str1 );setlink( head2, str2);head->next = ziplist( head1, head2 );head->next = findlist( head1, head2 );outlink( head );return 0; }void setlink( SNODE *head, char *str ) {SNODE *p ;while ( *str != '\0' ){ p = ( SNODE * ) malloc( sizeof( SNODE ) );p->data = *str;p->next = NULL;str++;head->next = p;head = p;}return; }void outlink( SNODE * head ) { while ( head->next != NULL ){printf( "%c", head -> next -> data );head = head -> next;}printf("\n");return; }int listlen( SNODE * head ) {int len=0;while ( head->next != NULL ){len ++;head = head->next;}return len; }SNODE * findlist( SNODE * head1, SNODE * head2 ) {int m, n;SNODE *p1=head1, *p2=head2;m = listlen( head1 );n = listlen( head2 );while ( m > n ){ p1 = p1->next;m--;}while ( m < n ){ p2 = p2->next;n--;}while( p1->next != NULL && p1->next != p2->next ){p1 = p1->next;p2 = p2->next;}return p1->next; } /* Here is waiting for you! */ /*SNODE * ziplist( SNODE * head1, SNODE * head2 ){} *//* PRESET CODE END - NEVER TOUCH CODE ABOVE */| 測(cè)試用例 1 | abcdef dbdef | def | 1秒 | 64M | 0 |
| 測(cè)試用例 3 | ation abation | ation | 1秒 | 64M | 0 |
解題思路
我們需要編寫的ziplist函數(shù)的功能已經(jīng)為我們描述好了:在兩個(gè)串鏈表中,查找公共后綴,若有公共后綴,則壓縮并返回指向公共后綴的指針;否則返回NULL。
而查找公共前綴的操作在findlist函數(shù)中已經(jīng)提示了,我們可以直接借鑒,需要處理的是壓縮公共前綴并返回其指針。
用一個(gè)flag來(lái)標(biāo)志當(dāng)前的后綴一定是最后面的公共后綴,用指針q1、q2分別表示單詞公共后綴的位置。修改指針使得單詞2的后綴指針指向單詞1的后綴指針,即實(shí)現(xiàn)壓縮。
上機(jī)代碼
SNODE * ziplist( SNODE * head1, SNODE * head2 ) {//使兩個(gè)單詞長(zhǎng)度一致int m=0 ,n=0;SNODE *p1=head1, *p2=head2;m=listlen(head1);n=listlen(head2);while(m>n){p1=p1->next;m--;}while(m<n){p2=p2->next;n--;}int flag=1;SNODE *q1=NULL, *q2=NULL;while(p1->next != NULL){if(p1->next->data == p2->next->data){if(flag)//確保是最后的相同后綴{flag=0;q1=p1;q2=p2;}}else{flag=1;q1=q2=NULL;}p1=p1->next;p2=p2->next;}if (q1 == NULL)//沒有相同后綴{return NULL;}else{//單詞指向同一后綴,實(shí)現(xiàn)壓縮q2->next=q1->next;return q1->next;} }總結(jié)