oral_quiz->#MoreThanHalfNum#

#include <stdio.h>
#include <exception>

void Swap(int* p1, int* p2) {
	int temp = *p1;
	*p1 = *p2;
	*p2 = temp;
}

int Partition(int* data, int length, int start, int end) {
	if(data == NULL || length <= 0 || start < 0 || end >= length)
		throw std::exception();

	int index = (start + end) >> 1;
	Swap(&data[index], &data[end]);

	int small = start - 1;
	for(index = start; index < end; ++index) {
		if(data[index] < data[end]) {
			++small;
			Swap(&data[small], &data[index]);
		}
	}

	++small;
	Swap(&data[small], &data[end]);

	return small;
}

bool g_bInputInvalid = false;

bool CheckInvalidArray(int* numbers, int length) {
	g_bInputInvalid = false;
	if(numbers == NULL || length <= 0)
		g_bInputInvalid = true;

	return g_bInputInvalid;
}

bool CheckMoreThanHalf(int* numbers, int length, int number) {
	int times = 0;
	for(int i=0; i<length; ++i) {
		if(numbers[i] == number)
			++times;
	}

	bool isMoreThanHalf = true;
	if(times * 2 <= length) {
		isMoreThanHalf = false;
		g_bInputInvalid = true;
	}

	return isMoreThanHalf;
}

int MoreThanHalfNum_Solution1(int* numbers, int length) {
	if(CheckInvalidArray(numbers, length))
		return 0;

	int start=0, end=length-1;
	int middle = length >> 1;
	int index = Partition(numbers, length, start, end);
	while(index != middle) {
		if(index > middle) {
			end = index - 1;
			index = Partition(numbers, length, start, end);
		}
		else {
			start = index + 1;
			index = Partition(numbers, length, start, end);
		}
	}

	int result = numbers[middle];
	if(!CheckMoreThanHalf(numbers, length ,result))
		result = 0;

	return result;
}

int MoreThanHalfNum_Solution2(int* numbers, int length) {
	if(CheckInvalidArray(numbers, length))
		return 0;

	int result = numbers[0];
	int times = 1;
	for(int i=1; i<length; ++i) {
		if(times == 0) {
			result = numbers[i];
			++times;
		}
		else if(result != numbers[i])
			--times;
		else
			++times;
	}

	if(!CheckMoreThanHalf(numbers, length, result))
		result = 0;

	return result;
}

// ====================测试代码====================
void Test(char* testName, int* numbers, int length, int expectedValue, bool expectedFlag)
{
    if(testName != NULL)
        printf("%s begins: \n", testName);

    int* copy = new int[length];
    for(int i = 0; i < length; ++i)
        copy[i] = numbers[i];

    printf("Test for solution1: ");
    int result = MoreThanHalfNum_Solution1(numbers, length);
    if(result == expectedValue && g_bInputInvalid == expectedFlag)
        printf("Passed.\n");
    else
        printf("Failed.\n");

    printf("Test for solution2: ");
    result = MoreThanHalfNum_Solution2(copy, length);
    if(result == expectedValue && g_bInputInvalid == expectedFlag)
        printf("Passed.\n");
    else
        printf("Failed.\n");

    delete[] copy;
}

// 存在出现次数超过数组长度一半的数字
void Test1()
{
    int numbers[] = {1, 2, 3, 2, 2, 2, 5, 4, 2};
    Test("Test1", numbers, sizeof(numbers) / sizeof(int), 2, false);
}

// 不存在出现次数超过数组长度一半的数字
void Test2()
{
    int numbers[] = {1, 2, 3, 2, 4, 2, 5, 2, 3};
    Test("Test2", numbers, sizeof(numbers) / sizeof(int), 0, true);
}

// 出现次数超过数组长度一半的数字都出现在数组的前半部分
void Test3()
{
    int numbers[] = {2, 2, 2, 2, 2, 1, 3, 4, 5};
    Test("Test3", numbers, sizeof(numbers) / sizeof(int), 2, false);
}

// 出现次数超过数组长度一半的数字都出现在数组的后半部分
void Test4()
{
    int numbers[] = {1, 3, 4, 5, 2, 2, 2, 2, 2};
    Test("Test4", numbers, sizeof(numbers) / sizeof(int), 2, false);
}

// 一个数
void Test5()
{
   int numbers[] = {1};
   Test("Test5", numbers, 1, 1, false);
}

// 输入空指针
void Test6()
{
    Test("Test6", NULL, 0, 0, true);
}

int main(int argc, char* argv[])
{
    Test1();
    Test2();
    Test3();
    Test4();
    Test5();
    Test6();

    return 0;
}



你可能感兴趣的:(半数)