下面是一个c++的函数,大致功能为在字符串中删除指定字符,有一点不理解的是s[j++]=s[i]这里是什么意思,不太理解其中的逻辑。
这就是将不是被删除字符的字符,都放置到数组开头位置。最后s[j]=0就是修改了字符串结束符的位置,使得按字符串输出时,就只有有效的字符了。
比如字符串aabba,你要删除a字符,那么j开始为0,当判断到b字符时,将b字符写到字符串的第0个位置,然后j++改为1;判断第二个b字符时,将它写到字符串的第1个位置,然后j++改为2。最后s[j]=0将第三个字符改成字符串结束符。这样字符串输出就只有bb两个字符,a字符全没有了
举个例子:1234删除3
s[j++]=s[i]即s[0]=s[0]
之后是s[1]=s[1]
由于s[2]==3,所有跳过赋值,此时j没有加一,但是i每次循环都加一
因此最后s[2]=s[3]
如果不为指定字符就保留 ,你这句话就相当于
s[j] = s[i];
j++;
因为只递增了 i ,所以 j也需要自增,在遇到指定字符时,j不自增,跳过,然后继续 s[j++] = s[i]也就是相当于把 指定字符后边的字符向前移动。
思路: 互动窗口及优化
关键字: 不重复字符
模式识别1: 一旦涉及出现次数, 需要用到散列表
构造子串, 散列表存下标
模式识别2: 涉及子串, 考虑滑动窗口
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if(s.size() == 0) return 0;
std::unordered_set<char> hashTable;
int Maxlen = 0;
int left = 0;
for(int i=0; i<s.size(); ++i){
while(hashTable.find(s[i]) != hashTable.end()){ //在散列表中搜索是否有重复字符
hashTable.erase(s[left]);
left++; //滑动窗口向右侧缩短至重复元素被移除为止
}
Maxlen = max(Maxlen,i-left+1);
hashTable.insert(s[i]);
}
return Maxlen;
}
};
答案:
这行代码 s[j++] = s[i] 的含义是把字符串 s 中下标为 i 的字符赋值到下标为 j 的位置,并使 j 自增。
这个函数的作用是删除 s 中所有等于 c 的字符。具体的实现思路是,在原字符串上进行修改,用指针 i 指向原字符串中的字符,用指针 j 指向修改后的字符串中的字符,如果字符不等于 c,则把该字符赋值到下标为 j 的位置,同时 j 自增 1。最后再把 j 位置后的字符都设置为 '\0',即表示新的字符串已经结束。
下面是该函数的完整代码实现:
void removeChar(char* s, char c) {
int i = 0, j = 0;
while (s[i] != '\0') {
if (s[i] != c) {
s[j++] = s[i];
}
i++;
}
s[j] = '\0';
}
其中,s[j++] = s[i] 表示先把 s[i] 赋值给 s[j],再把 j 自增 1。这么做的原因是,s[j] 表示修改后的新字符串中的下一个字符,而不是原字符串 s 中的下一个字符。
如果你想进一步优化这个函数,可以考虑使用标准库中的字符串操作函数(如 std::remove)。