从C ++代码中“就地”的C样式字符串中删除子字符串

时间:2018-10-24 15:14:57

标签: c++

我有一个采访任务,要在不使用字符串函数或其他内存的情况下从当前字符串中删除子字符串...我只是用strlen进行了尝试,但没有找到将其更改就位的方法... < / p>

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
int main()
{
    char * str = "this that there";
    char * substr = "th";
    removeSubstr(str,substr); 
    cout<<str;  //should be now "is at ere"

    return 0;
}
void removeSubstr(char * str, const char * substr){
}

2 个答案:

答案 0 :(得分:0)

存在字符串函数是有原因的。如果不使用它们,可以从头开始创建它们吗?

如果是这样,这是我对问题的解决方案。编写具有const要求的自定义字符串函数非常有教育意义。

如评论中所述,除非传入的字符串可以修改,否则它将无法工作,因此我将其设为非恒定字符串。

让我知道这是否满足面试挑战:

#include <iostream>

bool myStrnCmp(char *str1, const char *str2, int len) {
    char *cptr1 = (char *) str1;
    char *cptr2 = (char *) str2;
    for (int i = 0; i < len; i++) {
        if (*(cptr1 + i) != *(cptr2 + i))
            return false;
    }
    return true;
}

int mystrlen(const char* str) {
    int i = 0;
    while(*(str + i) != '\0')
        i++;
    return i;
}

int findSubStr(char *str, const char *substr) {
    int position = 0;
    int len = mystrlen(substr);

    while(*(str + position) != '\0') {
        for (int i = 0; i < len; i++) {
            if (myStrnCmp(str + position + i, substr, len))
                return position + i;
        }
        ++position;
    }
    return -1;
}

void myStrCpy(char *str, const char *substr) {
    memmove(str, substr, mystrlen(substr) + 1);

}

void removeSubstr(char *str, const char *substr) {
    int position = findSubStr(str, substr);
    while(position >= 0) {
        myStrCpy(str + position, str+position+mystrlen(substr));
        position = findSubStr(str, substr);
    }

}


int main() {
    char str[]{"this that there"};
    char* substr = "th";
    removeSubstr(str,substr);
    std::cout<<str;  //should be now "is at ere"

    return 0;
}

答案 1 :(得分:0)

  • 由于您从原始字符串中删除了字符,因此该字符串会缩小,因此您不需要其他空间。您只需将字符从较高的索引(源)复制到较低的索引(目标)。
  • 如果源索引指向以搜索到的子字符串开头的位置,则必须跳过它。
  • skip函数只是将源字符串的开头与子字符串进行比较,然后返回源(如果它不是以子字符串开头)或源加上子字符串的长度(如果它是以子字符串开头。

Demo

#include <iostream>

char* skip_if( char* s, const char* ss )
{
  char* p = s;
  const char* pp = ss;
  while( *p == *pp && *p )
    p++, pp++;
  return *pp ? s : p;
}

void remove( char* s, const char* ss )
{
  char *ps = s; // source
  char *pd = s; // destination
  while( *ps )
  {
    ps = skip_if( ps, ss );
    *pd++ = *ps++;
  }
  *pd = 0;
}

int main()
{
  using namespace std;

  char str[] = "this that there this that there";
  const char* substr = "th";
  remove( str, substr );

  cout << str;

  return 0;
}