[Sword Finger Offer] -Настройка положения нечетных и четных чисел в массиве

1. Положение регулировки не нужно менять относительное положение

Требования к теме

Введите массив целых чисел и реализуйте функцию, чтобы настроить порядок чисел в массиве так, чтобы все нечетные числа были в первой половине массива, а все четные числа - во второй половине массива.

Анализ темы

1.
Первая версия. Прежде всего, когда мы получим этот вопрос, у нас сразу появится идея сканировать массив с нуля. Всякий раз, когда встречается четное число, выньте это число и переместите все цифры за этим числом на один бит вперед, затем конечная позиция массива освобождается, а затем вставьте четное число в конец массива. Но это мышление все еще недостаточно. Поскольку временная сложность этой операции O (n ^ 2).
2. Версия 2
Мы можем принять стратегию обмена для решения проблемы. Давайте рассмотрим конкретный пример для подробного описания этого метода, а для массива рассмотрим массив {1,2,3,4,5}.
Сначала мы поддерживаем два указателя p1 и p2. Когда инициализируется p1, он указывает на первый номер массива, а когда инициализируется p2, он указывает на последний номер массива, как показано на следующем рисунке:
Вставьте описание изображения здесь
чтобы p1 указывал на четное число, p2 указывает на нечетное число, два указателя Укажите на позицию числа. Следовательно, р2 представляет собой нечетное число 5 очков без двигаться, двигаться вперед , когда p1 p1 номер точки 2, две цифровой коммутации
Вставьте описание изображения здесь
перемещается назад указатель p1, пока он не указывает четное число 4, указатель p2 двигаться вперед , пока он не указывает нечетное целое число ,
Вставьте описание изображения здесь
которое В это время, поскольку p2 переместился в начало p1, это указывает на то, что все нечетные числа находятся перед четными числами, и программа заканчивается.
Ключ к суммированию описанного выше процесса состоит в том, что, когда p1 указывает на четное число, а p1 указывает на нечетное число, позиция обмена числами, указанная двумя указателями, является условием для конца программы, что указатель p2 находится перед указателем p1.

Основываясь на приведенном выше анализе, мы можем написать наш код следующим образом:

void ReorderOddEvent(int* pData, unsigned int length)
{
	if (pData == nullptr || length <= 0)
		return;

	int* p1 = pData;
	int* p2 = pData + length - 1;

	while (p1 < p2)
	{
		//向后移动p1,直至他指向偶数
		while (p1 < p2 && (*p1 & 0x1) != 0)
			p1++;
		
		//向前移动p2,直至他指向奇数
		while (p1 < p2 && (*p2 & 0x1) == 0)
			p2--;

		if (p1 < p2)
		{
			int temp = *p1;
			*p1 = *p2;
			*p2 = temp;
		}
	}
}

3. Версия три
Способ второй версии выше решил проблему, необходимую в проблеме. Итак, если вы хотите, чтобы вы поняли, что все отрицательные числа в массиве находятся перед неотрицательными числами, что вам следует делать, если число, которое можно разделить на 3, стоит перед числом, которое нельзя разделить на 3? Если вы просто хотите изменить два условия в приведенном выше коде, это немного неправильно.
На самом деле, приведенный выше код не является расширяемым. Мы можем дать модель, в которой мы можем легко расширить существующие решения для проблем того же типа. Таким образом, мы можем сохранить большой кадр вышеприведенного кода без изменений и разделить всю функцию на две части: одна - определить, должно ли число быть в первой половине или второй половине массива, а вторая - разделить массив. Реализуйте критерии оценки с помощью указателей функций.

void Reorder(int* pData, unsigned int length,bool (*func)(int))
{
	if (pData == nullptr || length <= 0)
		return;

	int* p1 = pData;
	int* p2 = pData + length - 1;

	while (p1 < p2)
	{
		//向后移动p1,直至他指向偶数
		while (p1 < p2 && !func(*p1))
			p1++;

		//向前移动p2,直至他指向奇数
		while (p1 < p2 && func(*p2))
			p2--;

		if (p1 < p2)
		{
			int temp = *p1;
			*p1 = *p2;
			*p2 = temp;
		}
	}
}
bool isEven(int n)
{
	return (n & 0x01) == 0;
}
void ReorderOddEven(int* pData, unsigned int length)
{
	Reorder(pData, length, isEven);
}

Преимущество развязки - улучшенное повторное использование кода.

2. Регулировка положения требует, чтобы относительное положение оставалось неизменным

Требования к теме

Введите массив целых чисел и реализуйте функцию, чтобы настроить порядок чисел в массиве так, чтобы все нечетные числа были в первой половине массива, все четные числа были во второй половине массива, и убедитесь, что нечетные и нечетные числа, относительные между четными и четными числами Расположение не изменилось.

Анализ темы

В отличие от предыдущего вопроса, относительная позиция измененного массива должна быть неизменной, то есть массив {1,2,3,4,5} равен {1,3,5,2,4} после перемещения Вместо просто {1, 5, 3, 4, 2}.

В это время мы можем рассмотреть другой пробел, создать новый массив, сначала поместить нечетный push в исходный массив, а затем даже вставить, а затем перезаписать исходный массив новыми данными массива. Мы используем векторный контейнер для достижения, это будет более удобно. Такая временная сложность равна O (n).
Код реализован следующим образом:

void reOrderArray(vector<int> &array) {
         vector<int> res;
    for (int i = 0; i < array.size(); i++)
    {
        if (array[i] % 2 == 1)
        {
            res.push_back(array[i]);
        }
    }
    for (int i = 0; i < array.size(); i++)
    {
        if (array[i] % 2 == 0)
        {
            res.push_back(array[i]);
        }
    }
    array = res;
        
    }
Опубликовано 98 оригинальные статьи · вона похвала 9 · просмотров 3644

рекомендация

отblog.csdn.net/qq_43412060/article/details/105448917
рекомендация