XY
沒(méi)有任何借口
posts - 9, comments - 31, trackbacks - 0, articles - 0
C++博客
::
首頁(yè)
::
新隨筆
::
聯(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)該使用任何用于操縱字符串的庫(kù)函數(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ù)制
*/
;
/**/
/*
**空語(yǔ)句
*/
break
;
}
if
(flag)
strP
++
;
}
return
TRUE;
}
說(shuō)明:
最先str1的定義為 char *,然而就會(huì)出現(xiàn)while(*temp++ = *strP++)語(yǔ)句報(bào)錯(cuò)。報(bào)錯(cuò)誤寫入位置 0x00447240 時(shí)發(fā)生訪問(wèn)沖突,我的理解是因?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: 刪除字符串中的子串[未登錄](méi)
回復(fù)
更多評(píng)論
2008-06-04 16:11 by
raof01
感覺博主對(duì)于傳參方式(傳值)沒(méi)有理解。
函數(shù)原型有錯(cuò)誤:無(wú)法返回該字符串。感覺下面會(huì)好一點(diǎn):
char* del_substr(char* str, const char * substr);
說(shuō)不用字符串操作函數(shù),我就hack一把——自己寫操縱字符串的庫(kù)函數(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: 刪除字符串中的子串[未登錄](méi)
回復(fù)
更多評(píng)論
2008-06-04 16:15 by
raof01
這幾行代碼里面有寫錯(cuò)誤,不知道你看出來(lái)了沒(méi)有?呵呵。希望你能改掉這些錯(cuò)誤。
#
re: 刪除字符串中的子串
回復(fù)
更多評(píng)論
2008-06-05 01:41 by
passerby
為何不用KMP來(lái)比較字符呢
#
re: 刪除字符串中的子串
回復(fù)
更多評(píng)論
2008-06-05 10:13 by
路緣
@
raof01
確實(shí)有問(wèn)題,我現(xiàn)把更改的代碼貼在下面,但不知為為何說(shuō)我的方法無(wú)法返回字符串,對(duì)傳參方式?jīng)]有理解。del_substr(
char
*
str,
char
const
*
substr)傳遞的是主串指針的拷貝,但它和原字符串指針指向的是相同的位置,通過(guò)改變所指位置的內(nèi)容來(lá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
@路緣
看來(lái)沒(méi)有唬住你。你的理解是沒(méi)錯(cuò)的,呵呵。
除了del_substr(),別的還有問(wèn)題嗎?
#
re: 刪除字符串中的子串
回復(fù)
更多評(píng)論
2008-06-05 15:52 by
路緣
看來(lái)沒(méi)有唬住你。你的理解是沒(méi)錯(cuò)的,呵呵。
除了del_substr(),別的還有問(wèn)題嗎?
--------------------------------------------------------
@raof01,問(wèn)題我是找不出來(lái)了,不過(guò)我對(duì)比了哈C的庫(kù)函數(shù),你的代碼,
while (*str++) ++len;
不如庫(kù)函數(shù)中的
const char *eos = str;
while( *eos++ )
;
return( eos - str - 1 );
寫法效率高。
關(guān)于字符串的比較,跟庫(kù)函數(shù)的寫法的出入,我還得研究哈一些細(xì)節(jié)東西,看能不能琢磨出差別的用意。
如果代碼中還有其他問(wèn)題,還望@raof01不吝賜教,謝謝了。
#
re: 刪除字符串中的子串
回復(fù)
更多評(píng)論
2008-06-05 15:54 by
路緣
@passerby
謝謝你,KMP算法大學(xué)時(shí)學(xué)過(guò),謝謝你的提醒,你讓我知道事情不是做完那么簡(jiǎn)單,還得精益求精,我會(huì)抽時(shí)間,再寫一個(gè)改進(jìn)的算法來(lái)實(shí)現(xiàn)。
#
re: 刪除字符串中的子串
回復(fù)
更多評(píng)論
2008-06-05 17:51 by
raof01
@路緣
也沒(méi)啥問(wèn)題了——我沒(méi)有仔細(xì)考慮,時(shí)間緊,我只拿了5分鐘來(lái)寫這個(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)吧?沒(méi)有找到的時(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是什么類型?
刷新評(píng)論列表
只有注冊(cè)用戶
登錄
后才能發(fā)表評(píng)論。
【推薦】100%開源!大型工業(yè)跨平臺(tái)軟件C++源碼提供,建模,組態(tài)!
相關(guān)文章:
算法:快速排序之python實(shí)現(xiàn)
算法:找出n個(gè)數(shù)中重復(fù)最多的10個(gè)數(shù)
反轉(zhuǎn)字符串
刪除字符串中的子串
得到字符串S1中第一個(gè)且是字符串S2中的位置指針
網(wǎng)站導(dǎo)航:
博客園
IT新聞
BlogJava
博問(wèn)
Chat2DB
管理
Powered by:
C++博客
Copyright © 路緣
日歷
<
2008年6月
>
日
一
二
三
四
五
六
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
常用鏈接
我的隨筆
我的評(píng)論
我參與的隨筆
留言簿
(5)
給我留言
查看公開留言
查看私人留言
隨筆分類
(9)
C/C++(5)
計(jì)算機(jī)圖形學(xué)(1)
數(shù)字圖像
網(wǎng)絡(luò)通信
系統(tǒng)體系(2)
移動(dòng)開發(fā)(1)
隨筆檔案
(9)
2017年9月 (2)
2008年10月 (2)
2008年9月 (1)
2008年7月 (1)
2008年6月 (3)
博客
本人博客園的博客
搜索
積分與排名
積分 - 36146
排名 - 573
最新評(píng)論
1.?re: 反轉(zhuǎn)字符串
@周翀
剛一看,嚇我一跳,以為一直認(rèn)為的解法有問(wèn)題。細(xì)想一下,值相等也無(wú)妨。當(dāng)毀掉其中一個(gè)值后,再做異或,另一個(gè)值就會(huì)得到保留,做第3次計(jì)算,毀掉的那個(gè)值也被恢復(fù)了,所以沒(méi)有問(wèn)題。
--路緣
2.?re: 反轉(zhuǎn)字符串
三次異或可以互換兩個(gè)值,也可以毀掉兩個(gè)值,當(dāng)它們相等的時(shí)候……
--周翀
3.?re: 深入理解計(jì)算機(jī)系統(tǒng)1_程序是如何運(yùn)行的
抄襲
--圖—圖—
4.?re: 刪除字符串中的子串
ssize_t是什么類型?
--sb
5.?re: 刪除字符串中的子串
看錯(cuò)了~~sorry
--ff
閱讀排行榜
1.?反轉(zhuǎn)字符串(9811)
2.?深入理解計(jì)算機(jī)系統(tǒng)1_程序是如何運(yùn)行的(7956)
3.?刪除字符串中的子串(6642)
4.?分形的樂(lè)趣之_Hilbert曲線(2107)
5.?深入理解計(jì)算機(jī)系統(tǒng)2_信息存儲(chǔ)(2075)
評(píng)論排行榜
1.?刪除字符串中的子串(14)
2.?深入理解計(jì)算機(jī)系統(tǒng)1_程序是如何運(yùn)行的(12)
3.?反轉(zhuǎn)字符串(2)
4.?分形的樂(lè)趣之_Hilbert曲線(2)
5.?symbian應(yīng)用程序開發(fā)1(1)
伊人久久大香线蕉综合网站
|
久久人人爽人人爽人人片AV麻烦
|
久久久亚洲欧洲日产国码是AV
|
久久精品一区二区三区中文字幕
|
99久久精品无码一区二区毛片
|
久久久久亚洲Av无码专
|
亚洲精品蜜桃久久久久久
|
亚洲人成网亚洲欧洲无码久久
|
久久强奷乱码老熟女网站
|
久久中文字幕精品
|
久久人人爽人人爽人人片AV麻烦
|
无码任你躁久久久久久久
|
久久99久久无码毛片一区二区
|
久久精品成人欧美大片
|
蜜桃麻豆www久久国产精品
|
伊人色综合九久久天天蜜桃
|
久久久久久久综合狠狠综合
|
精产国品久久一二三产区区别
|
伊人久久久AV老熟妇色
|
无码久久精品国产亚洲Av影片
|
热RE99久久精品国产66热
|
伊人久久大香线蕉无码麻豆
|
久久国产色av免费看
|
久久午夜羞羞影院免费观看
|
大伊人青草狠狠久久
|
九九久久精品国产
|
久久精品国产亚洲AV蜜臀色欲
|
久久无码人妻一区二区三区午夜
|
国产精品久久影院
|
久久久久九九精品影院
|
无码日韩人妻精品久久蜜桃
|
青青草国产精品久久
|
亚洲精品国产综合久久一线
|
久久精品国产亚洲77777
|
国产精品成人久久久久三级午夜电影
|
久久久久婷婷
|
久久久久亚洲AV无码永不
|
国产精品热久久无码av
|
无遮挡粉嫩小泬久久久久久久
|
99久久国产亚洲高清观看2024
|
99久久这里只精品国产免费
|