void RemoveSpace(char *String)
{
int i=0,y=0;
int leading=0;
for(i=0,y=0;String[i]!='\0';i++,y++)
{
String[y]=String[i]; // let us copy the current character.
if(isspace(String[i])) // Is the current character a space?
{
if(isspace(String[i+1])||String[i+1]=='\0'||leading!=1) // leading space
y--;
}
else
leading=1;
}
String[y]='\0';
}
这是否可以删除前导空格和尾随空格并用单个空格替换多个空格? 我测试了它的空字符串,所有空格,前导空格和尾随空格。
您认为这是一种有效的一次通过解决方案吗?
答案 0 :(得分:0)
根据您的代码,假设您的iswhite()效率很高, (你可能不会把它分开,因为它太频繁了) 假设传入的字符串本身是有效的(应该更具防御性)
=======================
void RemoveSpace(char *String)
{
int i=0, j=0;
int inWhite=0;
char c = String[i++];
while(c)
{
if (isspace(c))
{
inWhite= 1;
}
else
{
// there are space before, and not beginning
if (inWhite && j > 0)
{
String[j++] = ' ';
}
String[j++] = c;
inWhite = 0;
}
c = String[i++];
}
String[j]='\0';
}
未经测试,请自行测试......
答案 1 :(得分:0)
以下代码应该这样做:
void rem_space(char *str)
{
int len = strlen(str) - 1;
int i = 0;
int spaces = 0;
if(str == NULL) return;
while(i < len){
while(str[i] == ' ') {spaces++; i++;}
while(str[i] != ' ' && str[i] != '\0') {str[i - spaces] = str[i]; i++;}
if(str[i + spaces - 1] != '\0') {
str[i - spaces] = ' '; spaces--;
} else {
break;
}
}
str[i - spaces] = '\0';
return;
}
答案 2 :(得分:0)
这是否可以解决前导和尾随空格并用单个空格替换多个空格?
回答这个问题的最好方法是测试它。
void Test(const char *input, const char *expected_output) {
char buffer[80];
strcpy(buffer, input);
RemoveSpace(buffer);
assert(strcmp(buffer, expected_output) == 0);
}
int main() {
Test(" Leading spaces removed.", "Leading spaces removed.");
Test("Trailing spaces removed. ", "Trailing spaces removed.");
Test("Inner spaces trimmed.", "Inner spaces trimmed.");
Test(" A little of everything. ", "A little of everything.");
Test(" \tTabs \t\tare \t spaces, too.", "Tabs are spaces, too.");
return 0;
}
OP中的代码未通过最后一次测试,因此答案为否。
您认为这是一种有效的一次性解决方案吗?
这是一次性解决方案。如果你试图挤出每一盎司的效率,那么你想要最小化操作和条件分支的数量。
在C语言中使用C字符串时,使用指针而不是索引通常最惯用。根据编译器和目标平台,使用指针可能比索引更高效或更低效,但两者都是非常低的成本。由于这已经是单个线性传递,因此最好的做法是尽可能清晰地使用惯用代码模式进行编写。
这是我的解决方案:
#include <assert.h>
#include <ctype.h>
#include <string.h>
void RemoveSpace(char *string) {
char *target = string;
char *last = target;
int skipping_spaces = 1;
for (const char *source = string; *source != '\0'; ++source) {
if (isspace(*source)) {
if (!skipping_spaces) {
*target++ = *source;
skipping_spaces = 1;
}
} else {
*target++ = *source;
last = target;
skipping_spaces = 0;
}
}
*last = '\0';
}
它本质上是一个小状态机,这意味着,在每一步,我们根据当前输入字符和当前状态决定做什么。对于这个问题,我们的状态就是我们当前是否正在跳过空格(以及一个跟踪最后一个合法点以结束字符串的书签)。
答案 3 :(得分:0)
首先,显然,这是一次通过。但是,当输入具有多个前导空格时,它会出现问题。例如:
输入:" text"
输出:" text"
幸运的是,它很容易解决。你只需要一个额外的循环:
void RemoveSpace(char *string)
{
int i = 0, y = 0;
while(isspace(string[i])) // Discard leading spaces.
i++;
for(y = 0; string[i]!='\0'; i++)
{
string[y] = string[i]; // let us copy the current character.
if(!isspace(string[i]) || !isspace(string[i+1]) && !string[i+1]=='\0')
y++; // This character shall not be covered.
}
string[y] = '\0';
}
我也进行了一些更改,以使您的代码看起来更好,这实际上是无关紧要的。
答案 4 :(得分:0)
'''
导入操作符 ...
返回“” .join(filter(lambda a:operator.is_not(a,“”), line .strip()。split(“”))) '''