2012-02-07 88 views
0

我在C#下面的代碼反轉的字符串:轉換C#和C++按位移

char[] charArray = s.ToCharArray(); 
int len = s.Length - 1; 

for (int i = 0; i < len; i++, len--) 
{ 
    charArray[i] ^= charArray[len]; 
    charArray[len] ^= charArray[i]; 
    charArray[i] ^= charArray[len]; 
} 

return new string(charArray); 

我試圖將其轉換爲C++作爲一種智力活動比什麼都重要。以下是我迄今爲止:

void main(void) 
{ 
    char* str = "testing"; 
    char* result; 
    int len; 

    len = strlen(str); 

    if (len <= 12) 
    { 
     result = new char[strlen(str)]; 
     for (int i = 0; i < len; i++, len--) 
     { 
      result[i] ^= str[len]; 
      result[len] ^= str[i]; 
      result[i] ^= str[len]; 
     } 
    } 
    else{ 
     std::reverse(str, &str[strlen(str)]); 
    } 

    cout << endl << result << endl; 

    // cleanup 
    str = NULL; 
    result = NULL; 
} 

在.NET中字符串是否< = 12(我認爲這是十二)個異比陣列反向快。 Source - Sam Saffron我基本上是想看看它是否仍然用C舉起++。

字符串出來,在一個奇怪的格式(════╣¥¿ë²²²要準確)。

任何想法?

注意:我知道else語句不工作,出來後我就明白這一點;)

注2:我可能做這完全錯了,可以隨意點絕對什麼出格

更新

感謝大家參加。我沒有在一個公平幾年與C++播放(它顯示),並認爲這將是安靜容易轉換,但顯然不是。認爲我放棄這個想法是最好的。再次感謝

+5

這是在性能的嘗試,但你正在使用C字符串,XOR交換,堆分配,指數法,而不是迭代器和調用strlen的兩倍? – Pubby 2012-02-07 00:11:45

+2

提示:保證在C++中的* result *緩衝區的初始內容是什麼? – 2012-02-07 00:15:52

+0

只需添加參考源。我完全承認我不知道我在做什麼。純粹的智力鍛鍊:)我正在緩存它,但由於某種原因不使用它:/ – 2012-02-07 00:15:52

回答

2

有幾件事情:

result = new char[strlen(str)]; 

應該

result = new char[len + 1]; 

len因爲你已經計算出的str長度,+ 1以騰出空間NUL終止。

其次,你需要在它在操作之前的字符串複製到result,否則你的陣列是滿垃圾,否則的:

strcpy(result, str); 

第三,

std::reverse(str, &str[strlen(str)]); 

是錯誤的,原因有二:一,因爲你不能修改字符串和二,因爲你應該使用result

std::reverse(result, result + len); 

但是,如果你這樣做,你還需要str複製到result第一。

最後,指針設置爲NULL不釋放它所指向的內存。你必須

delete[] result; // delete[] because new[] 

注意,對於這即使在else取(因此result不言指向分配的內存),你需要做的

char* result = NULL; // delete[] is defined as a nop on NULL pointers 

工作如果您確定要使用C字符串,上述所有內容都適用。一旦你指針的竅門,你可以升級到std::string

std::string str("testing"); 

std::reverse(std::begin(str), std::end(str)); // or if you don't want to do it in-place, 
               // std::string result(str.rbegin(), str.rend()); 
+0

感謝您的信息。我是否還需要'刪除[] str'?我嘗試過,但它扔了一個錯誤? – 2012-02-07 00:35:00

+1

@StuartBlackler否,因爲它沒有被分配'new []'。規則是:**每個'new'都有一個'delete',每個'new []'**只有一個'delete []'。事實證明,字符串文字(通常)駐留在可執行文件的內存中,並保存整個程序(通常在只讀內存中,但即使內存權限未被明確讀取,也不允許修改它們)只有),這就是爲什麼你不能修改它。 – 2012-02-07 00:37:11

+0

非常感謝:) – 2012-02-07 00:38:56

1

做的更好的方式,更多的C++,更低的C

std::string mystring = "testing"; 

std::string reversed; 

for(std::string::iterator str_it = mystring.rbegin(); str_it != mystring.rend(); ++str_it) 
{ 
    reversed += *str_it; 
} 

std::cout << reversed << std::endl; 
+3

更好的是,'std :: string reversed(mystring.rbegin(),mystring.rend());'。 – ildjarn 2012-02-07 00:24:23

+1

@ildjarn好點。沒想到那麼遠 – 2012-02-07 00:25:09

2

XOR交換是用於交換。如果你正在複製一個result數組,那麼這是分配,而不是交換。而且,你只能在數組中進行迭代,否則你需要交換兩次。

下面是C#代碼的轉譯:

#include <iostream> 
#include <algorithm> 

int main(void) 
{ 
    char str[] = "testing"; // arrays have automatic storage - no need to new/delete 
    const size_t str_len = sizeof(str)-1; // sizeof(str) returns size of the array 

    if (str_len <= 12) // because str_len is a constant expression, the other branch will be compiled-out 
    { 
     // this should probably use iterators (pointers) but oh well 
     for (size_t i = 0, len = str_len-1; i < str_len/2; i++, len--) 
     { 
      str[i] ^= str[len]; 
      str[len] ^= str[i]; 
      str[i] ^= str[len]; 
     } 
    } 
    else{ 
     std::reverse(str, str + str_len); // str decays to a pointer 
    } 

    std::cout << str << '\n'; // don't use endl if you don't need to flush 
} 

這是非常糟糕的代碼。只需使用std::stringstd::reverse即可。它比xor快,只有2行。

std::string str = "testing" 
std::reverse(str.begin(), str.end()); 
+0

考慮到這裏的大量信息,我認爲我會放棄這個智力練習(認爲轉換爲C++會更容易,但顯然不會)。請問爲什麼需要XOR交換檢查? – 2012-02-07 00:51:55

+2

@Stuart:數字XOR本身總是0. – ildjarn 2012-02-07 00:52:55

+0

@StuartBlackler它不是必需的,但可以將您從不必要的xors中拯救出來(用相同的字母替換字母沒有意義)。 – 2012-02-07 00:57:48