我已经有了从C中的字符串(word)中删除子字符串的代码,但我不明白。有人可以向我解释一下吗?它不使用标准库中的函数。我自己试图分析它,但某些部分我仍然不明白 - 我把它们放在评论中。我只需要弄清楚这一切是如何运作的。
谢谢!
#include <stdio.h>
#include <stdlib.h>
void remove(char *s1, char *s2);
int main()
{
char s1[101], s2[101];
printf("First word: ");
scanf("%s", s1);
printf("Second word: ");
scanf("%s", s2);
remove(s1, s2);
printf("The first word after removing is '%s'.", s1);
return 0;
}
void remove(char *s1, char *s2)
{
int i = 0, j, k;
while (s1[i]) // ITERATES THROUGH THE FIRST STRING s1?
{
for (j = 0; s2[j] && s2[j] == s1[i + j]; j++); // WHAT DOES THIS LINE DO?
if (!s2[j]) // IF WE'RE AT THE END OF STRING s2?
{
for (k = i; s1[k + j]; k++) //WHAT DOES THIS ENTIRE BLOCK DO?
s1[k] = s1[k + j];
s1[k] = 0;
}
else
i++; // ???
}
}
答案 0 :(得分:2)
这里函数的主要工作如下:
-Skip两个字符串之间的公共部分,并为第一个字符串分配新字符串。
while (s1[i]) // Yes It ITERATES THROUGH THE FIRST STRING s1
{
for (j = 0; s2[j] && s2[j] == s1[i + j]; j++); // Here it skips the part which is
//similar in both
由于此循环只是增加了公共部分的索引,因此这将跳过在s1中存储数据。
if (!s2[j]) // IF WE'RE AT THE END OF STRING s2
{
for (k = i; s1[k + j]; k++) //Here it is re assigning the non common part.
s1[k] = s1[k + j];
s1[k] = 0;
}
else
i++; // it is req. if both have more values.
}
答案 1 :(得分:1)
第一个while (s1[i])
遍历s1。是的,你是对的。
for (j = 0; s2[j] && s2[j] == s1[i + j]; j++);
上面的for循环检查从s1 [i]开始s1中是否存在子串s2。如果匹配,则s2完全迭代。如果不是,在for循环结束时,s2 [j]将不是空字符。示例:如果s1 = ITERATE且s2 = RAT,则仅当i = 3时,循环才会完全执行。
所以if (!s2[j])
成立,那就意味着我们找到了一个子串,而i是s1中子串的起点。
for (k = i; s1[k + j]; k++) //WHAT DOES THIS ENTIRE BLOCK DO?
s1[k] = s1[k + j];
s1[k] = 0;
abov块删除子字符串。因此,对于ITERATE和RAT示例,这是通过在存在R和A的位置复制E和null char来完成的。 for循环实现了这一点。如果在for循环之后s2 [j]不为空,则i递增以检查来自s1的下一个位置的子分配。
答案 2 :(得分:1)
以下是评论中隐含的功能方法
void remove(char *s1, char *s2)
{
int i = 0, j, k;
while (s1[i]) // Iterates through s1 (until it finds a zero)
{
for (j = 0; s2[j] && s2[j] == s1[i + j]; j++); // Iterates through s2 while both it is NOT the end of the string s2 and each character of s2 coincides with s1 (if s2 == s1, j points to the end of s2 => zero)
if (!s2[j]) // If j point to the end of s2 => We've found the coincidence
{
for (k = i; s1[k + j]; k++) //Remove the coincident substring
s1[k] = s1[k + j];
s1[k] = 0;
}
else
i++; // There is no coincidence so we continue to the next character of s1
}
}
注意:我也注意到这可能很容易被解释,因为它迭代了s1范围。
答案 3 :(得分:1)
让我们分解吧。
while (s1[i])
{
// Code
}
这遍历s1
。一旦到达字符串的末尾,就有\0
,这是空终止符。在条件中进行评估时,它将评估为0
。在这里使用for
可能更好。
然后你有
for (j = 0; s2[j] && s2[j] == s1[i + j]; j++);
这只会增加j
。应该注意的是,这个表达式没有大括号,并以分号结束,因此后面的代码不应该在循环体内执行。如果它确实有正确的大括号,它将循环遍历以下if/else
,而s2
不为空且s2[j] == s1[i+j]
。除s2
中的字符偏移i
中的s1
字符外,我对第二部分没有真正的解释。可能会改进此部分以删除不必要的迭代。
然后就是
if (!s2[j])
{
}
else
{
}
检查以确保s2
中的位置有效并执行删除字符串(如果是),否则增加i
。当else
s2
不再适合s1
的其余部分时,可以通过返回for (k = i; s1[k + j]; k++)
s1[k] = s1[k + j];
s1[k] = 0;
来改进。
s1[k] = 0
这是另一个有点奇怪的循环,因为没有大括号,s2
将被设置在循环之外。这里发生的是通过删除k+j
并将k
处的字符向下移动到s1[k] = 0
来压缩字符串。在循环结束时import java.io.*;
public class Strbuff
{
public static void main(String arg[])throws IOException
{
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
String str;
try
{
System.out.println("Enter your name");
str=in.readLine();
str+="\nThis is example for string Buffer class and its function";
StringBuffer strbuf=new StringBuffer();
strbuf.append(str);
System.out.println(strbuf);
strbuf.delete(0,str.length());
strbuf.append("hello");
strbuf.insert(5,"-java");
System.out.println(strbuf);
strbuf.reverse();
System.out.println("Reversed string");
System.out.println(strbuf);
strbuf.reverse();
System.out.println(strbuf);
strbuf.setCharAt(5,' ');
System.out.println(strbuf);
System.out.println("Character at 6th position");
System.out.println(strbuf.substring(3,7));
strbuf.deleteCharAt(3);
System.out.println(strbuf);
System.out.println("Capacity of the string Buffer object");
System.out.println(strbuf.capacity());
strbuf.delete(6,strbuf.length());
System.out.println("The string with first 6 letters");
System.out.println(strbuf);
}
catch(StringIndexOutOfBoundsException e)
{
System.out.println(e.getMessage());
}
}
}
结束空终止符中的字符串以正确结束。
如果你想要更深入的理解,可能值得尝试编写自己的代码来做同样的事情然后进行比较。我发现这通常比阅读大量测试更有帮助。