編輯:我想我已經理解了這個概念是如何作業的,這是我的代碼
void delete_duplicate(char* str) {
if (str == NULL) {
exit(1);
}
for (size_t i = 0; str[i] != 0; i ) {
if (str[i] == str[i 1]) {
str[i] = '\0';
}
}
}
int main(void) {
char str[] = "hhhhhhhheeeeeeeeyyyyyyyyyyy";
delete_duplicate(str);
return 0;
}
輸出字串是“00...0h0...000e0...000y”(有很多零)。如果字串是“abbbb”,則字串變為“a”而不是“ab”。
我正在考慮這個練習的演算法:
給定一個字串,例如“sststringg”,輸出必須是“string”。當且僅當當前字符和下一個字符相同時,該函式必須洗掉一個字符。
練習需要一個這樣宣告的函式:
extern void delete_consecutive(char* str);
這是我的演算法:
- 回圈:如果當前字符等于下一個字符,則將長度增加 1,并重復直到到達零終止符。
關鍵部分:動態記憶體分配。
- allocate enough memory to store the output. Why did I say this is the critical part? because I have to do it in a void function, therefore I can't create a second string, allocate enough memory with malloc, and then return it at the end. I need to edit the original string instead. I think I can do it by means of a realloc, and by decrementing the size of the string. But I don't know how to do it, and more important: I don't know if it's legit to do it, without losing data. I think I'm overcomplicating the homework, but it's a void function, therefore I can't simply create a new string and copying characters in it, because I can't return it.
if it's not clear, I'll edit the question.
uj5u.com熱心網友回復:
這種模式稱為保留掃描(也稱為縮減掃描,取決于您的觀點),并且在根據某些條件決定丟棄字符同時保留其他字符的演算法中非常常見。通常情況會發生變化,有時甚至開始掃描的方法也會有所改變
在最簡單的形式中,它看起來像這樣,例如: 一種用于丟棄除數字(數字)字符之外的所有字符的演算法:
- 從字串頭部的讀取器
r和寫入器指標開始。w - 使用 . 從頭到尾遍歷字串
r。每次迭代,指標總是會精確遞增r一次。 - 對于每次迭代,檢查當前字符是否
r滿足保留條件(在這種情況下,字符是數字字符嗎?)。如果是這樣,請將其寫入w并前進w一個插槽。 - 等結束了。
w將指向您的終結器應該駐留的位置。
#include <ctype.h>
void delete_nondigits(char *s)
{
if (s && *s)
{
char *w = s;
for (char *r = s; *r; r)
{
if (isdigit((unsigned char)*r))
*w = *r;
}
*w = 0;
}
}
很簡單。
現在,就地連續運行壓縮的演算法更加復雜,但具有高度相似的模型。因為保留基于已經保留的先前值,所以您需要記住最后保留的值。您可以只使用,但如果您將其保存在單獨的備忘錄中*w,該演算法實際上更容易理解(和改進),因為您將要看到:wchar
- 像以前一樣從讀取器
r和寫入器w指標開始,但從字串的第二個槽開始,并且將單個 memochar變數c初始化為字串的第一個字符。 r使用直到終止遇到遍歷字串。每次迭代,指標總是會精確遞增r一次。- 對于每次迭代,檢查當前字符 at
*r是否與備忘錄字符相同,c如果是,則不執行任何操作并繼續下一次迭代。 - 否則,如果 at 的字符
*r與備注字符不同c,則將其保存為 的新值c,寫入*w,然后前進w一個槽。 - 完成后,通過在 處設定終止符來終止字串
*w。
該演算法的唯一障礙是在開始時支持零長度字串,通過首先檢查單個條件很容易繞過。我把它作為練習留給你。(s && *s)(提示:僅當為真時才執行上述操作)。
uj5u.com熱心網友回復:
如果可修改,您可以修改作為引數傳遞的字串。
例子:
void deleteFirstChar(char *str)
{
if(str && *str)
{
memmove(str, str 1, strlen(str));
}
}
//illegal call
//string literals cannot be changed
void foo(void)
{
char *str = "Hello";
deleteFirstChar(str);
}
//legal call
void bar(void)
{
char str[] = "Hello";
deleteFirstChar(str);
}
uj5u.com熱心網友回復:
這不是答案,但請考慮以下代碼:
char str[] = "strunqg";
printf("before: %s\n", str);
modifystring(str);
printf("after: %s\n", str);
其中“ modifystring”函式如下所示:
void modifystring(char *p)
{
p[3] = 'i';
p[5] = p[6];
p[6] = '\0';
}
這完全是“合法的”。但是,呼叫它是行不通的
char *str = "strunqg";
modifystring(str); /* WRONG */
或者
modifystring("strunqg"); /* WRONG */
后兩個中的任何一個都將嘗試修改字串文字,而這不是合意的。
uj5u.com熱心網友回復:
void delete_duplicate(char* str)
{
if(str && *str)
{
char *writeTo = str, *readFrom = str;
char prev = 0;
while(*readFrom)
{
if(prev != *readFrom)
{
prev = *readFrom ;
*writeTo = prev;
}
else
{
readFrom ;
}
}
*writeTo = 0;
}
}
int main(void)
{
char str[] = "hhhhhhhheeeeeeeeyyyyyyyyyyy";
delete_duplicate(str);
printf("`%s`\n", str);
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/424334.html
標籤:c algorithm memory-management
上一篇:字串中的最小替換以使所有'X'字符位于所有'Y字符的左側
下一篇:獲取凸包索引
