Last active
October 25, 2016 10:33
-
-
Save piratf/4cd4d859727cd65542be1387f7debf14 to your computer and use it in GitHub Desktop.
判断数组是不是等差数列的时间 O(n),空间 O(1) 算法 - 这个算法是不正确的
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdio> | |
#include <vector> | |
#include <assert.h> | |
#include <limits> | |
// #include <iostream> | |
static int main_ret = 0; | |
static int test_count = 0; | |
static int test_pass = 0; | |
#define EXPECT_EQ_BASE(equality, expect, actual, format) \ | |
do {\ | |
test_count++;\ | |
if (equality)\ | |
test_pass++;\ | |
else {\ | |
fprintf(stderr, "%s:%d: expect: " format " actual: " format "\n", __FILE__, __LINE__, expect, actual);\ | |
main_ret = 1;\ | |
}\ | |
} while(0) | |
#define EXPECT_EQ_BOOL(expect, actual) EXPECT_EQ_BASE((expect) == (actual), expect, actual, "%d") | |
void calu(const std::vector<int> &vecArr, int &i32Min, int &i32Max, unsigned long long &u64Sum) { | |
assert(vecArr.size()); | |
i32Min = vecArr[0]; | |
i32Max = vecArr[0]; | |
for (int var : vecArr) { | |
if (var < i32Min) { | |
i32Min = var; | |
} else if (var > i32Max) { | |
i32Max = var; | |
} | |
u64Sum += var; | |
} | |
} | |
inline int calTolerance(int i32Min, int i32Max, size_t size) { | |
return (i32Max - i32Min) / (size - 1); | |
} | |
void calOffSquareSum(const std::vector<int> &vecArr, int i32Base, unsigned long long &u64Sum) { | |
--i32Base; | |
for (int var : vecArr) { | |
u64Sum += (var - i32Base) * (var - i32Base); | |
assert(static_cast<unsigned long long>(std::numeric_limits<signed long long>().max()) > u64Sum); | |
} | |
} | |
inline unsigned long long calOffSquareSum(const unsigned long long u32Tolerance, const unsigned long long u32Num) { | |
unsigned long long Z = (((u32Num - 1) * u32Num) * (2 * u32Num - 1)) / 6; | |
return (u32Num) + u32Tolerance * u32Tolerance * Z + 2 * u32Tolerance * ((u32Num * (u32Num - 1)) / 2); | |
// return (u32Num * 1) + u32Tolerance * u32Tolerance * Z + 2 * 1 * u32Tolerance * ((u32Num * (u32Num - 1)) / 2); | |
} | |
bool IsArithmeticProgression(const std::vector<int> &vecArr) { | |
int i32Min = 0, i32Max = 0; | |
unsigned long long u64Sum = 0, u64OffsetSquareSum = 0; | |
calu(vecArr, i32Min, i32Max, u64Sum); | |
calOffSquareSum(vecArr, i32Min, u64OffsetSquareSum); | |
// std::cout << "start >>>" << std::endl; | |
// std::cout << "u64Sum = " << u64Sum << ' ' << "i32Min = " << i32Min << ' ' << "i32Max = " << i32Max << std::endl; | |
// std::cout << "u64Sum = " << u64Sum << ' ' << "calSum = " << (static_cast<unsigned long long>((vecArr.size() * (i32Min + i32Max))) >> 1) << std::endl; | |
if (static_cast<unsigned long long>((vecArr.size() * (i32Min + i32Max))) >> 1 != u64Sum) { | |
return false; | |
} | |
int i32Tolerance = calTolerance(i32Min, i32Max, vecArr.size()); | |
// std::cout << "d = " << i32Tolerance << std::endl; | |
for (int var : vecArr) { | |
if (var != i32Min + ((var - i32Min) / i32Tolerance) * i32Tolerance) { | |
// std::cout << "Not Aliquots, quit" << std::endl; | |
return false; | |
} | |
} | |
// std::cout << "u64OffsetSquareSum = " << u64OffsetSquareSum << ' ' << "Cal OffsetSquareSum = " << calOffSquareSum(i32Tolerance, vecArr.size()) << std::endl; | |
return u64OffsetSquareSum == calOffSquareSum(i32Tolerance, vecArr.size()); | |
} | |
void test_bool() { | |
EXPECT_EQ_BOOL(true, IsArithmeticProgression({1, 2, 3, 4, 5})); | |
EXPECT_EQ_BOOL(false, IsArithmeticProgression({1, 2, 2, 5, 5, 6})); | |
EXPECT_EQ_BOOL(false, IsArithmeticProgression({1, 2, 3, 5, 5, 6})); | |
EXPECT_EQ_BOOL(true, IsArithmeticProgression({-2, -1, 0, 1, 2})); | |
EXPECT_EQ_BOOL(false, IsArithmeticProgression({-2, -2, 0, 2, 2})); | |
EXPECT_EQ_BOOL(true, IsArithmeticProgression({-2, 1, 4, 7, 10})); | |
EXPECT_EQ_BOOL(true, IsArithmeticProgression({1, 3, 5, 7, 9, 11, 13})); | |
EXPECT_EQ_BOOL(false, IsArithmeticProgression({1, 2, 6, 7, 9, 11, 13})); | |
EXPECT_EQ_BOOL(true, IsArithmeticProgression({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13})); | |
// 构造出了例外情况,该算法是错误的 | |
EXPECT_EQ_BOOL(false, IsArithmeticProgression({1, 2, 2, 5, 6, 6, 7, 7, 9, 10, 11, 12, 13})); | |
} | |
void test() { | |
test_bool(); | |
printf("%d/%d (%3.2f%%) passed\n", test_pass, test_count, test_pass * 100.0 / test_count); | |
} | |
int main() { | |
test(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment