[英]How can I tweak this algorithm to deal with multiple occurrences of a keyword to modify?
我想搜索所有出現的字符串(第一個參數),並在所有出現的第一個字符串之前添加另一個字符串(第二個參數)。
理想情況下,我希望每次出現的dime
都可以被limedime
代替。 但是,我僅在單詞首次出現時才做到這一點。 不會檢測到任何不是第一個的匹配字符串,並且不會執行任何操作。 另外,包含dime
多行會基於對前幾行所做的修改而被修改,這不是我想要的。
這是我得到的一些示例輸出:
something dime something dime something something
會變成
something limedime something dime something something
如果我有這個
dime
notimportant!
dime
dime
我會得到
limedime
notimportant!
limelimedime
limelimelimedime
編輯:我已經修改了代碼,因此您可以輕松地使用stdin
對其進行測試,並且還包括replace_str()
:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
char *replace_str(char *str, char *orig, char *rep)
{
static char buffer[4096];
char *p;
if(!(p = strstr(str, orig)))
return str;
strncpy(buffer, str, p-str);
buffer[p-str] = '\0';
sprintf(buffer+(p-str), "%s%s", rep, p+strlen(orig));
return buffer;
}
void replace(char* patternoo, char* replacearoo){
char buff[BUFSIZ]; // the input line
char newbuff[BUFSIZ]; // the results of any editing
char pattern[200];
strcpy(pattern, patternoo);
char replace[200];
strcpy(replace, replacearoo);
while ( fgets( buff, BUFSIZ, stdin ) != NULL ) {
if ( strstr( buff, pattern ) != NULL ) {
//THIS IS WHERE WE DO pattern replacing
strcpy(newbuff, replace_str(buff, pattern, strcat(replace,pattern)));
} else {
strcpy( newbuff, buff );
}
printf("%s", newbuff);
}
}
int main(){
replace("dime", "lime");
}
現在,我想也許這種方式不太好,因為我只看線條? 我不確定該怎么做,逐個閱讀每個字符? 對我來說似乎有點多,但我不確定。 有什么快速而骯臟的方法可以修復我當前的算法嗎? 還是我必須重新開始並采用全新的方法?
假設您在每次出現dime
之前都插入了lime
,則需要讀取一行,在輸入緩沖區中找到每次出現的dime
,然后在找到時將輸入緩沖區的未處理部分復制到輸出緩沖區,然后添加lime
,然后添加dime
,然后在dime
之后恢復搜索。
轉換為:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
static void replace(char *pattern, char *replace)
{
char buff[BUFSIZ]; // the input line
char newbuff[BUFSIZ]; // the results of any editing
size_t replen = strlen(replace);
size_t patlen = strlen(pattern);
while (fgets(buff, BUFSIZ, stdin) != NULL)
{
newbuff[0] = '\0';
char *dst = newbuff;
char *data = buff;
char *patt;
while ((patt = strstr(data, pattern)) != NULL)
{
memmove(dst, data, (patt - data));
dst += (patt - data);
memmove(dst, replace, replen);
dst += replen;
memmove(dst, pattern, patlen);
dst += patlen;
data = patt + patlen;
}
*dst = '\0';
printf("%s%s", newbuff, data);
}
}
int main(void)
{
replace("dime", "lime");
return 0;
}
該代碼巧妙地忽略了輸入行超長擴展的存在-您需要進行工作以確保它不會溢出輸出緩沖區。 由於每個dime
(4個字符)都插入了4個字符( lime
),因此最糟糕的是,輸出中需要的空間是輸入中空間的兩倍。 因此,更改newbuff[2 * BUFSIZ]
的大小將解決那些溢出問題-對於要添加前綴的特定字符串。 輸入線過長也可能導致丟失。 如果一dime
在兩個緩沖區已滿的邊界上分開,它將被丟失。
給定一個名為data
的文件(從您的問題中摘錄):
something dime something dime something something
should become
something limedime something limedime something something
and if I have this
dime
not important!
dime
dime dime
dime dime dime
I will get limes and dimes galore:
limedime
not important!
limedime
limedime limedime
limedime limedime limedime
運行程序( repstr
,我稱之為)的輸出為:
$ ./repstr < data
something limedime something limedime something something
should become
something limelimedime something limelimedime something something
and if I have this
limedime
not important!
limedime
limedime limedime
limedime limedime limedime
I will get limes and limedimes galore:
limelimedime
not important!
limelimedime
limelimedime limelimedime
limelimedime limelimedime limelimedime
$
一種方法可能是:
Have a temp string that displays output.
Until whole sentence read
Read complete word of that sentence.
if that word == dime
append limedime to temp string
else append the same word to temp string.
Dryrun:
input: something dime somthing lime dime
iteration1: something read compare it with lime, they arent equal so append somthing to temp string.
temp: something
iteration2: word read: dime
temp: something limedime
iteration3: word read: something
temp: something limedime something
and soo on.
希望這種方法有幫助:)
很久沒有接觸過C了,所以我忘記了它的語法,所以在編寫偽代碼方面無濟於事。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.