将C#转换为C++位移位
本文关键字:C++ 转换 | 更新日期: 2023-09-27 18:22:41
我在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(我认为是12)xor比数组反转快。来源:Sam Saffron我基本上是想看看它在C++中是否仍然有效。
字符串的格式很奇怪(════╣准确地说是人民币)。
有什么想法吗?
注意:我知道else语句不起作用,我会在;)
注意2:我可能做得完全错误,所以请随意指出的任何内容
更新
感谢所有参与的人。我已经有好几年没有玩过c++了(这表明了),我认为它很容易转换,但显然不是。我想我最好放弃这个想法。再次感谢
几件事:
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());
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::string
和std::reverse
。它比xor快,只有2行长。
std::string str = "testing"
std::reverse(str.begin(), str.end());
一种更好的方法,更多的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;