• <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>

            XY

            沒有任何借口
            posts - 9, comments - 31, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            刪除字符串中的子串

            Posted on 2008-06-04 14:09 路緣 閱讀(6642) 評(píng)論(14)  編輯 收藏 引用 所屬分類: C/C++
            題目:
                     請(qǐng)編寫一個(gè)函數(shù),刪除一個(gè)字符串的一部分。函數(shù)原型如下:
                           int del_substr(char *str, char const *substr)
                     函數(shù)首先應(yīng)判斷substr是否出現(xiàn)在str中。如果它并未出現(xiàn),函數(shù)就返回0;如果出現(xiàn),函數(shù)應(yīng)該把str中位于該子串后面的所有字符復(fù)制到該子串的位置,從而刪除這個(gè)子串,然后函數(shù)返回1。如果substr多次出現(xiàn)在str中,函數(shù)只刪除第1次出現(xiàn)的子串。函數(shù)的第2個(gè)參數(shù)絕不會(huì)被修改。
                     舉個(gè)例子,假定str指向ABCDEFG。如果substr指向FGH、CDF或XABC,函數(shù)應(yīng)該返回0,str未作任何修改。但如果substr指向CDE,函數(shù)就把str修改為指向ABFG,方法是把F、G和結(jié)尾的NUL字節(jié)復(fù)制到C的位置,然后函數(shù)返回1。不論出現(xiàn)什么情況,函數(shù)的第2個(gè)參數(shù)都不應(yīng)該被修改。
                    要求:a.你不應(yīng)該使用任何用于操縱字符串的庫函數(shù)(如strcpy, strcmp, 等)。
                                b.函數(shù)中的任何地方都不應(yīng)該使用下標(biāo)引用。
                   一個(gè)值得注意的是,空字符串是每個(gè)字符串的一個(gè)子串,如果字符串中刪除一個(gè)空字符串不會(huì)產(chǎn)生變化。
            算法:
            #include <stdlib.h>
            #include 
            <stdio.h>

            #define TRUE 1
            #define FALSE 0

            /*********************************************************
            函數(shù)聲明
            */

            int del_substr(char *str, char const *substr);
            /*********************************************************
            主函數(shù)
            */

            int main()
            {
                
            char str1 [] = "aabcdefgh324";
                
            char const * str2= "abc";

                printf(
            "before delete: %s\n", str1);
                printf(
            "will delete che chars: %s\n", str2);
                del_substr(str1, str2);
                printf(
            "After delete: %s\n", str1);

                system(
            "pause");
                
            return 0;
            }

            /***刪除字符串str中包含的子串substr,不進(jìn)行重復(fù)刪除*/
            int del_substr(char *str, char const *substr)
            {
                
            char const * subP;
                
            char *strP;
                
            char *temp;
                
            int flag = TRUE;

                strP 
            = str;
                
            if((!*str) || *substr == '\0')/***如果主串為空或子串為空字符串,則返回*/
                    
            return FALSE;

                
            while(*strP)
                
            {        
                    temp 
            = strP;
                    
            for(subP=substr; *subP; subP++)
                    
            {
                        
            if(*strP == *subP)/***如果當(dāng)前的主串和子串字符相等*/
                        
            {
                            strP++;/**//***則主串指針向前移一個(gè)字符*/
                            flag = FALSE;/**//*設(shè)置為false,防止后續(xù)的主串指針,重復(fù)移動(dòng)*/
                            continue;
                        }
                        
            break;
                    }

                    
                    
            if(*subP == '\0'/***如果subP指向末尾的'\0'則表示子串匹配成功*/
                    
            {
                        
            while(*temp++ = *strP++)/***進(jìn)行字符復(fù)制*/
                            ;
            /***空語句*/
                        
            break;
                    }

                    
            if(flag)
                        strP
            ++;
                }

                
            return TRUE;
            }

            說明:
                   最先str1的定義為 char *,然而就會(huì)出現(xiàn)while(*temp++ = *strP++)語句報(bào)錯(cuò)。報(bào)錯(cuò)誤寫入位置 0x00447240 時(shí)發(fā)生訪問沖突,我的理解是因?yàn)樽址羔榯emp指向的是字符串常量,不允許進(jìn)行修改。所以定義為
                     char str1 [] 很關(guān)鍵。
                   經(jīng)上網(wǎng)查資料,解釋是:
                   C++中數(shù)據(jù)存儲(chǔ)區(qū)分為五種:
            棧、堆(new分配)、自由存儲(chǔ)區(qū)(malloc分配)、全局/靜態(tài)變量存儲(chǔ)區(qū)、常量存儲(chǔ)區(qū)(不允許修改,除非采用特殊手段)。 字符串這種常量就存在常量區(qū)中。全局、靜態(tài)變量放在靜態(tài)存儲(chǔ)區(qū),而它們是可以被修改的。

            Feedback

            # re: 刪除字符串中的子串[未登錄]  回復(fù)  更多評(píng)論   

            2008-06-04 16:11 by raof01
            感覺博主對(duì)于傳參方式(傳值)沒有理解。
            函數(shù)原型有錯(cuò)誤:無法返回該字符串。感覺下面會(huì)好一點(diǎn):
            char* del_substr(char* str, const char * substr);
            說不用字符串操作函數(shù),我就hack一把——自己寫操縱字符串的庫函數(shù),呵呵……:
            ssize_t Strlen(const char* str)
            {
            ssize_t len = 0;
            while (*str++) ++len;
            return len;
            }

            int StrCmp(const char* str1, const char* str2, ssize_t len)
            {
            for (int i = 0; i < len; ++i)
            {
            if (*(str1 + i) != *(str2 + i))
            return (*(str1 + i) - *(str2 + i));
            }
            return 0;
            }

            char* del_substr(char* str, const char * substr)
            {
            char* temp = NULL;
            ssize_t len = Strlen(substr);
            while (*substr++ && *str++)
            {
            if (*substr == *str)
            {
            if (!StrCmp(substr, str, len))
            {
            temp = str + len;
            while (*temp++)
            {
            *str++ = *temp;
            }
            break;
            }
            }
            }
            return str;
            }

            # re: 刪除字符串中的子串[未登錄]  回復(fù)  更多評(píng)論   

            2008-06-04 16:15 by raof01
            這幾行代碼里面有寫錯(cuò)誤,不知道你看出來了沒有?呵呵。希望你能改掉這些錯(cuò)誤。

            # re: 刪除字符串中的子串  回復(fù)  更多評(píng)論   

            2008-06-05 01:41 by passerby
            為何不用KMP來比較字符呢

            # re: 刪除字符串中的子串  回復(fù)  更多評(píng)論   

            2008-06-05 10:13 by 路緣
            @raof01
            確實(shí)有問題,我現(xiàn)把更改的代碼貼在下面,但不知為為何說我的方法無法返回字符串,對(duì)傳參方式?jīng)]有理解。del_substr(char *str, char const *substr)傳遞的是主串指針的拷貝,但它和原字符串指針指向的是相同的位置,通過改變所指位置的內(nèi)容來達(dá)到改變?cè)址哪康摹?/span>
             
            關(guān)于你提供的代碼,我修改如下。還是謝謝你的熱心回復(fù)。讓我同時(shí)也學(xué)了一些東西
            char* del_substr(char* str, const char * substr) 

                
            char* temp = NULL, *cp = str; 
                ssize_t len 
            = Strlen(substr); 
                
            while (*str) 
                

                    
            if (*substr == *str) 
                    

                        
            if (!StrCmp(substr, str, len)) 
                        

                            temp 
            = str + len; 
                            
            while (*str++ = *temp++
                                ;
                            
            break
                        }
             
                    }
             
                    str
            ++;
                }
             
                
            return cp; 
            }
             
             

            # re: 刪除字符串中的子串  回復(fù)  更多評(píng)論   

            2008-06-05 13:11 by raof01
            @路緣
            看來沒有唬住你。你的理解是沒錯(cuò)的,呵呵。
            除了del_substr(),別的還有問題嗎?

            # re: 刪除字符串中的子串  回復(fù)  更多評(píng)論   

            2008-06-05 15:52 by 路緣
            看來沒有唬住你。你的理解是沒錯(cuò)的,呵呵。
            除了del_substr(),別的還有問題嗎?
            --------------------------------------------------------
            @raof01,問題我是找不出來了,不過我對(duì)比了哈C的庫函數(shù),你的代碼,
            while (*str++) ++len;
            不如庫函數(shù)中的
            const char *eos = str;
            while( *eos++ )
            ;
            return( eos - str - 1 );
            寫法效率高。

            關(guān)于字符串的比較,跟庫函數(shù)的寫法的出入,我還得研究哈一些細(xì)節(jié)東西,看能不能琢磨出差別的用意。

            如果代碼中還有其他問題,還望@raof01不吝賜教,謝謝了。

            # re: 刪除字符串中的子串  回復(fù)  更多評(píng)論   

            2008-06-05 15:54 by 路緣
            @passerby
            謝謝你,KMP算法大學(xué)時(shí)學(xué)過,謝謝你的提醒,你讓我知道事情不是做完那么簡(jiǎn)單,還得精益求精,我會(huì)抽時(shí)間,再寫一個(gè)改進(jìn)的算法來實(shí)現(xiàn)。

            # re: 刪除字符串中的子串  回復(fù)  更多評(píng)論   

            2008-06-05 17:51 by raof01
            @路緣
            也沒啥問題了——我沒有仔細(xì)考慮,時(shí)間緊,我只拿了5分鐘來寫這個(gè)。

            # re: 刪除字符串中的子串  回復(fù)  更多評(píng)論   

            2008-07-09 10:20 by chu
            效率似乎太低了點(diǎn)

            # re: 刪除字符串中的子串  回復(fù)  更多評(píng)論   

            2008-12-03 16:33 by 佰銳科技
            StrCmp 應(yīng)該改為StrNCmp

            # re: 刪除字符串中的子串  回復(fù)  更多評(píng)論   

            2010-01-08 14:30 by ff
            if(flag)
            strP++;
            后少了點(diǎn)吧?沒有找到的時(shí)候死循環(huán)了吧?
            加else break;可以解決~

            # re: 刪除字符串中的子串  回復(fù)  更多評(píng)論   

            2010-01-08 15:03 by ff
            char* del_substr(char* str, const char * substr)
            {
            char* temp = NULL, *cp = str;
            ssize_t len = Strlen(substr);
            while (*str)
            {
            if (*substr == *str)
            {
            if (!StrCmp(substr, str, len))
            {
            temp = str + len;
            while (*str++ = *temp++)
            ;
            break;
            }
            }
            str++;
            }
            return cp;
            } 能刪除全部出現(xiàn)的子字符串,但是“如果substr多次出現(xiàn)在str中,函數(shù)只刪除第1次出現(xiàn)的子串”,這段代碼會(huì)把重復(fù)出現(xiàn)的也刪除。。。

            # re: 刪除字符串中的子串  回復(fù)  更多評(píng)論   

            2010-01-08 15:07 by ff
            看錯(cuò)了~~sorry

            # re: 刪除字符串中的子串  回復(fù)  更多評(píng)論   

            2010-03-13 00:47 by sb
            ssize_t是什么類型?
            午夜精品久久久久成人| 国产精品久久免费| 91精品国产色综久久| 蜜臀av性久久久久蜜臀aⅴ| 亚洲一级Av无码毛片久久精品| 国产精品久久久久久久久免费| 日日躁夜夜躁狠狠久久AV| 中文字幕无码av激情不卡久久| 久久av高潮av无码av喷吹| 久久这里只有精品首页| 精品久久久久久中文字幕| 国内精品九九久久久精品| 无码人妻久久一区二区三区免费丨| 伊人精品久久久久7777| 欧美色综合久久久久久| 日韩久久无码免费毛片软件| 少妇久久久久久被弄到高潮| 久久人妻少妇嫩草AV无码蜜桃| 国产亚洲成人久久| 久久久久一本毛久久久| 久久久综合香蕉尹人综合网| 老司机午夜网站国内精品久久久久久久久 | 久久er99热精品一区二区| 色诱久久久久综合网ywww| 久久精品国产亚洲av水果派 | 久久无码AV中文出轨人妻| 伊人色综合久久天天人守人婷 | 亚洲国产精品综合久久一线| 亚洲国产成人精品久久久国产成人一区二区三区综 | 精品久久久久久久国产潘金莲| 亚洲精品无码久久久久AV麻豆| 97视频久久久| 国产精品无码久久综合| 国产免费久久精品丫丫| 亚洲欧美成人久久综合中文网| 亚洲va久久久噜噜噜久久天堂| 欧美黑人又粗又大久久久| 国产精品成人无码久久久久久 | 久久精品中文无码资源站| 色综合久久88色综合天天| 欧美亚洲日本久久精品|