Skip to content

Instantly share code, notes, and snippets.

@piratf
Last active October 25, 2016 10:33
Show Gist options
  • Save piratf/4cd4d859727cd65542be1387f7debf14 to your computer and use it in GitHub Desktop.
Save piratf/4cd4d859727cd65542be1387f7debf14 to your computer and use it in GitHub Desktop.
判断数组是不是等差数列的时间 O(n),空间 O(1) 算法 - 这个算法是不正确的
#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