2010-03-16 80 views
3
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

根據你的代碼,假設你的字符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'; 
} 

沒有測試,請測試自己...

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; 
} 
+0

由於strlen,這是兩次通過。 – 2016-02-16 15:40:00

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'; 
} 

它本質上是一個小的狀態機,這意味着,在每一步,我們決定基於當前輸入字符和當前狀態做什麼。對於這個問題,我們的狀態就是我們是否正在跳過空格(還有一個書籤記錄最後一個結束字符串的合法點)。

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'; 
} 

我也做了一些修改,使你的代碼看起來更好,這實際上是不相關的。

相關問題