Преобразование C # в C ++ побитовый сдвиг - PullRequest
0 голосов
/ 07 февраля 2012

У меня есть следующий код в 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 (я думаю, что это двенадцать), xor быстрее, чем обратный массив. <a href="https://stackoverflow.com/a/228062/315711"> Источник - Сэм Саффрон Я пытаюсь выяснить, сохранился ли он в C ++.

Строка выходит в странном формате (точнее, ═════ ¥ ¿ë²²²).

Есть идеи?

Примечание : я знаю, что оператор else не работает, я это выясню позже;)

Примечание 2 : Возможно, я делаю это совершенно неправильно, поэтому не стесняйтесь указывать абсолютно на все

Update

Спасибо всем, кто принял участие. Я не играл с c ++ уже несколько лет (и это видно) и думал, что конвертировать будет легко, но, очевидно, нет. Думаю, лучше отказаться от этой идеи. Еще раз спасибо

Ответы [ 3 ]

2 голосов
/ 07 февраля 2012

xor swap предназначен для обмена.Если вы копируете в массив 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());
2 голосов
/ 07 февраля 2012

Несколько вещей:

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

Все вышесказанное применимо, если вы уверены, что хотите использовать Си-струны.Как только вы освоитесь с указателями, вы можете перейти к 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());
1 голос
/ 07 февраля 2012

Лучший способ сделать это, больше 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...