2014-03-19 9 views
0

Я только недавно приступил к C++, и я с трудом сдвигая элементы массива, чтобы удалить пустые/нулевые элементыC++ сдвиг элементов массива влево

char *aBlock; 
aBlock = new char[100]; 

int main(int argc, char **argv) 
{ 
aBlock[20] = 'a'; // fill array with test data. 
aBlock[10] = 's'; 
aBlock[30] = 'd'; // Excepted output: This test data should be shifted to the start of array 

// Consider aBlock contains data, with random empty elements 
    for(int i=1; i <= aBlock.length(); i++) { 
     if(aBlock[i-1] == 0) { 
      aBlock[i-1] = aBlock[i]; 
      aBlock[i] = 0; 
     } 
    } 

    return 0; 
} 

Edit: Исправлен код опечатку & неправильные имена переменных, изменились "==" - "=". Он по-прежнему не работает должным образом.

+0

Замечание о терминологии: массив не может иметь «пустые» элементы. В вашем случае вы, кажется, хотите удалить элементы со значением '== 0'. – juanchopanza

+2

Что такое '.length()' указателя в первую очередь? – deviantfan

+0

@juanchopanza Учитывая приведенный выше код, я бы назвал aBlock [50] пустым, поскольку ему ничего не назначено. Какова была бы правильная терминология для описания ее состояния? – AgentOrange

ответ

0

Если я правильно понял, вы хотите переместить ненулевые элементы в начале вашего массива. Вы можете использовать std::remove_if сделать это и установить остальные элементы на 0.

std::fill(
    std::remove_if(std::begin(aBlock), std::end(aBlock), [](char const c) {return c == '\0'; }), 
    std::end(aBlock), 
    0); 

UPDATE:

Поскольку массив выделяется динамически вам необходимо небольшое изменение:

std::fill(
    std::remove_if(&aBlock[0], &aBlock[100], [](char const c) {return c == '\0'; }), 
    &aBlock[100], 
    0); 
+0

Хорошая идея, бит в этом случае 'std :: end' не будет работать, потому что массив динамически распределяется. Кроме того, в этом случае было бы проще использовать 'std :: remove'. – juanchopanza

+0

Уверен, что это было бы, просто не с 'begin' и' end'. Но вы можете использовать '& aBlock [0]' и '& aBlock [100]'. –

+0

Нет идеи, что вы имели в виду, но по крайней мере теперь это сработает. Я до сих пор не вижу причины использовать 'remove_if' над' remove'. Это кажется ненужным осложнением. – juanchopanza

0

изменение

memBlock[i-1] == memBlock[i]; 

в

memBlock[i-1] = memBlock[i]; 

"==" проблема я думаю.

использование

 if(aBlock[i-1] != 0) 
+0

Хотя это может быть очевидная ошибка, это не очень поможет. Он пытается называть 'length()' на 'char *' например. Код не будет компилироваться вообще. – Excelcius

0

== Оператору проверяет равенство, вы должны использовать = назначить.

memBlock[i-1] = memBlock[i]; 

Массивы в C++ не какой-либо элемент, как .length(). Они не классы.

for(int i=1; i <= 100; i++) 
        ^^^ 
0

Если вы знаете размер во время компиляции, используйте std :: array, если он доступен. Затем вы можете сделать «.size()» :) Кроме того, ваш код не работает, если у вас несколько последовательных нулей. Каждый элемент сдвигается не более одного раза, что явно недостаточно для достижения желаемого результата. Что вам нужно сделать, это следить за отдельный «выход» индекса/итератора, который принимает любое ненулевое значение, которое вы сталкиваетесь, а затем увеличивается на единицу:

std::array<char, 100> aBlock; 
aBlock[10] = 's'; 
aBlock[20] = 'a'; 
aBlock[30] = 'd'; 

auto output = aBlock.begin(); // or aBlock if you don't have std::array; 
for (auto input = aBlock.begin(); input != aBlock.end(); ++input) 
{ 
    if (*input != 0) 
    { 
    if (output != input) 
    { 
     *output = input; 
     *input = 0; 
    } 
    ++output; 
    } 
} 

Это должно сделать трюк.

+0

Я не знаю размер массива во время компиляции, могу ли я создать std: array во время выполнения? Это упростит ситуацию. – AgentOrange

+0

Нет, но для этого вы обычно используете std :: vector, который может быть динамически изменен (vector.resize (100) будет содержать 100 нулей). Остальная часть кода останется идентичной. – heinrichj

0
int arrsize = 100; 

... 

int i, j; 
for(i = 0, j = 0; i < arrsize ; i++) { 
    if(memBlock[i] != 0 && i != j) { 
     memBlock[j++] = memBlock[i]; 
     memBlock[i] = 0; 
    } 
} 

Сторона примечания: новое в глобальном пространстве? А где is delete []?

+0

Вы должны проверить свой собственный код :) – heinrichj

+0

Пожалуйста, причина тоже. Может быть, я слишком устал, но я не вижу проблемы. – deviantfan

+1

Тот факт, что вы назначаете memBlock [i] = 0, если вы только что протестировали, это должно вызвать тревогу. – heinrichj

Смежные вопросы