如何删除字符串中偶数出现的子字符串
How to remove even occurences of a substring in a string
我正在尝试删除甚至出现的子字符串,例如,如果我有 A11B11C11 并且我想删除 11,它将删除位置 0 和 2 上的那些,因此它应该看起来像 AB11C。
这是我到目前为止的功能,它删除了所有出现的情况。
void removeSubstr(char* s, char* c)
{
int poz = -1;
int i = 0;
int string_length = strlen(s);
int number_length = strlen(c);
while (i < string_length) {
if (strstr(&s[i], c) == &s[i]) {
poz++;
if (poz % 2 == 0) {
string_length -= number_length;
for (int j = i; j < string_length; j++) {
s[j] = s[j + number_length];
}
}
}
else {
i++;
}
}
printf("'%d'", poz);
s[i] = '[=10=]';
}
我的方法是,每当我发现一个事件时,我应该将它添加到一个计数器中,并且每当计数器可以被 2 整除时,我删除子字符串,但它总是删除所有子字符串。
编辑:
if (strstr(&s[i], c) == &s[i]) {
poz++;
if (poz % 2 == 0) {
string_length -= number_length;
for (int j = i; j < string_length; j++) {
s[j] = s[j + number_length];
}
}
else {
i++; //added this
}
}
正如评论中所说,当出现奇怪的情况时,我也必须增加 i,现在它起作用了。
对于初学者来说,该函数应该 return 修改后的源字符串。此外,由于子字符串在函数内未更改,因此应使用限定符 const
声明相应的函数参数
char * removeSubstr( char *s1, const char *s2 );
从源字符串的每个字符开始调用函数strstr
while (i < string_length) {
if (strstr(&s[i], c) == &s[i]) {
效率不高。子字符串最初可以在源字符串中不存在。
此外,如果您有这样的源字符串 "A11111"
那么结果字符串似乎应该类似于 "A111"
因为在第一个子字符串 "11"
被删除后,当在此字符串中时“ A111”子串“11”是奇数,不能去掉。
但是使用您的方法您将得到结果字符串 "A1"
。那是在你应该写的 else 语句中
else {
i += number_length;
}
我会按照下面的演示程序所示的方式编写函数。
#include <stdio.h>
#include <string.h>
char * removeSubstr( char *s1, const char *s2 )
{
size_t pos = 0;
size_t n1 = strlen( s1 ), n2 = strlen( s2 );
for ( char *prev = s1, *next = s1 ; ( next = strstr( prev, s2 ) ) != NULL; prev = next )
{
n1 -= next - prev - n2;
if ( pos++ % 2 == 0 )
{
memmove( next, next + n2, n1 + 1 );
}
else
{
next = prev + n2;
}
}
return s1;
}
int main( void )
{
char s1[] = "A11B11C11";
const char *s2 = "11";
printf( "\"%s\"\n", s1 );
printf( "\"%s\"\n", removeSubstr( s1, s2 ) );
}
程序输出为
"A11B11C11"
"AB11C"
我正在尝试删除甚至出现的子字符串,例如,如果我有 A11B11C11 并且我想删除 11,它将删除位置 0 和 2 上的那些,因此它应该看起来像 AB11C。 这是我到目前为止的功能,它删除了所有出现的情况。
void removeSubstr(char* s, char* c)
{
int poz = -1;
int i = 0;
int string_length = strlen(s);
int number_length = strlen(c);
while (i < string_length) {
if (strstr(&s[i], c) == &s[i]) {
poz++;
if (poz % 2 == 0) {
string_length -= number_length;
for (int j = i; j < string_length; j++) {
s[j] = s[j + number_length];
}
}
}
else {
i++;
}
}
printf("'%d'", poz);
s[i] = '[=10=]';
}
我的方法是,每当我发现一个事件时,我应该将它添加到一个计数器中,并且每当计数器可以被 2 整除时,我删除子字符串,但它总是删除所有子字符串。
编辑:
if (strstr(&s[i], c) == &s[i]) {
poz++;
if (poz % 2 == 0) {
string_length -= number_length;
for (int j = i; j < string_length; j++) {
s[j] = s[j + number_length];
}
}
else {
i++; //added this
}
}
正如评论中所说,当出现奇怪的情况时,我也必须增加 i,现在它起作用了。
对于初学者来说,该函数应该 return 修改后的源字符串。此外,由于子字符串在函数内未更改,因此应使用限定符 const
char * removeSubstr( char *s1, const char *s2 );
从源字符串的每个字符开始调用函数strstr
while (i < string_length) {
if (strstr(&s[i], c) == &s[i]) {
效率不高。子字符串最初可以在源字符串中不存在。
此外,如果您有这样的源字符串 "A11111"
那么结果字符串似乎应该类似于 "A111"
因为在第一个子字符串 "11"
被删除后,当在此字符串中时“ A111”子串“11”是奇数,不能去掉。
但是使用您的方法您将得到结果字符串 "A1"
。那是在你应该写的 else 语句中
else {
i += number_length;
}
我会按照下面的演示程序所示的方式编写函数。
#include <stdio.h>
#include <string.h>
char * removeSubstr( char *s1, const char *s2 )
{
size_t pos = 0;
size_t n1 = strlen( s1 ), n2 = strlen( s2 );
for ( char *prev = s1, *next = s1 ; ( next = strstr( prev, s2 ) ) != NULL; prev = next )
{
n1 -= next - prev - n2;
if ( pos++ % 2 == 0 )
{
memmove( next, next + n2, n1 + 1 );
}
else
{
next = prev + n2;
}
}
return s1;
}
int main( void )
{
char s1[] = "A11B11C11";
const char *s2 = "11";
printf( "\"%s\"\n", s1 );
printf( "\"%s\"\n", removeSubstr( s1, s2 ) );
}
程序输出为
"A11B11C11"
"AB11C"