Compare commits

...

7 Commits

Author SHA1 Message Date
2b67094dcf feat: add cross checker test 5. 2025-05-19 22:06:18 +08:00
5948001ce9 feat: add cross checker test 3 and test 4. 2025-05-19 22:04:38 +08:00
7b14919dac feat: add cross checker test2. 2025-05-19 22:02:13 +08:00
d2483eb095 feat: add cross checker test1. 2025-05-19 21:59:41 +08:00
3bfb4dde2e feat: add quiz 3 cross-checker. 2025-05-19 21:56:26 +08:00
a4624b477f feat: add quiz 2 counter. 2025-05-19 21:26:47 +08:00
651bc79d2e fix: gtest build failed. 2025-05-19 21:11:57 +08:00
15 changed files with 292 additions and 2 deletions

View File

@@ -1,8 +1,10 @@
cmake_minimum_required(VERSION 3.10) cmake_minimum_required(VERSION 3.10)
project(plct_lab) project(plct-lab)
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)
add_subdirectory(third-party/googletest-1.17.0) add_subdirectory(third-party/googletest-1.17.0)
add_subdirectory(mixplus) add_subdirectory(mixplus)
add_subdirectory(counter)
add_subdirectory(cross-checker)

18
README.md Normal file
View File

@@ -0,0 +1,18 @@
# PLCT LAT TEST
## Build
```bash
make build
cd build
cmake ..
make
```
Three test will be in:
- mixplus
- counter
- cross-checker
There are unit-tests implemented by gtest.

11
counter/CMakeLists.txt Normal file
View File

@@ -0,0 +1,11 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src SRC)
add_library(libcount STATIC ${SRC})
add_executable(counter main.cpp)
target_link_libraries(counter libcount)
add_subdirectory(tests)

16
counter/include/counter.h Normal file
View File

@@ -0,0 +1,16 @@
#pragma once
#include <string>
#include <unordered_map>
namespace counter
{
struct Counter
{
static std::unordered_map<std::string, long> count(const std::string& input);
static void countPair(std::unordered_map<std::string, long>& map, const std::string& input);
static void countTriple(std::unordered_map<std::string, long>& map, const std::string& input);
};
}

21
counter/main.cpp Normal file
View File

@@ -0,0 +1,21 @@
#include <counter.h>
#include <iostream>
int main(const int argc, char** argv)
{
if (argc != 2)
{
std::cout << "ERROR: Need a string." << std::endl;
}
const std::string input(argv[1]);
const auto map = counter::Counter::count(input);
for (const auto& pair : map)
{
std::cout << pair.first << ' ' << pair.second << std::endl;
}
return 0;
}

34
counter/src/counter.cpp Normal file
View File

@@ -0,0 +1,34 @@
#include "counter.h"
void counter::Counter::countPair(std::unordered_map<std::string, long>& map, const std::string& input)
{
for (int i = 1; i < input.size(); i++)
{
const auto pair = input.substr(i - 1, 2);
map[pair] += 1;
}
}
void counter::Counter::countTriple(std::unordered_map<std::string, long>& map, const std::string& input)
{
for (int i = 2; i < input.size(); i++)
{
const auto pair = input.substr(i - 2, 3);
map[pair] += 1;
}
}
std::unordered_map<std::string, long> counter::Counter::count(const std::string& input)
{
std::unordered_map<std::string, long> map;
countPair(map, input);
countTriple(map, input);
return map;
}

View File

@@ -0,0 +1,10 @@
enable_testing()
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} TEST_SRC)
add_executable(
counter_tests
${TEST_SRC}
)
target_link_libraries(counter_tests GTest::gtest_main libcount)

View File

View File

@@ -0,0 +1,11 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src SRC)
add_library(libcross-checker STATIC ${SRC})
add_executable(cross-checker main.cpp)
target_link_libraries(cross-checker libcross-checker)
add_subdirectory(tests)

View File

@@ -0,0 +1,38 @@
//
// Created by ricardo on 19/05/25.
//
#ifndef CROSS_CHECKER_H
#define CROSS_CHECKER_H
namespace cross_checker
{
// 既可以表示点也可以表示一个向量
struct Point
{
double x;
double y;
Point(const double a, const double b) : x(a), y(b)
{
}
static int orientation(const Point& p, const Point& q, const Point& r);
static bool onSegment(const Point& p, const Point& q, const Point& r);
};
struct Line
{
Point startPoint;
Point endPoint;
Line(const Point a, const Point b): startPoint(a), endPoint(b)
{
}
bool intersect(const Line& other);
};
}
#endif //CROSS_CHECKER_H

24
cross-checker/main.cpp Normal file
View File

@@ -0,0 +1,24 @@
#include <cross-checker.h>
#include <iostream>
int main(int argc, char** argv)
{
if (argc != 9)
{
std::cout << "ERROR: 4 point must be provided" << std::endl;
}
cross_checker::Line line1(cross_checker::Point(std::stod(argv[1]), std::stod(argv[2])), cross_checker::Point(
std::stod(argv[3]), std::stod(argv[4])));
cross_checker::Line line2(cross_checker::Point(std::stod(argv[5]), std::stod(argv[6])), cross_checker::Point(
std::stod(argv[7]), std::stod(argv[8])));
if (line1.intersect(line2))
{
std::cout << "TRUE" << std::endl;
}
else
{
std::cout << "FALSE" << std::endl;
}
}

View File

@@ -0,0 +1,58 @@
#include <cmath>
#include <algorithm>
#include "cross-checker.h"
// 计算向量叉积的方向
// 返回值:
// 0 表示三点共线
// 1 表示逆时针方向(正)
// -1 表示顺时针方向(负)
int cross_checker::Point::orientation(const Point& p, const Point& q, const Point& r)
{
const double val = (q.x - p.x) * (r.y - p.y) - (r.x - p.x) * (q.y - p.y);
if (std::fabs(val) < 1e-9) return 0; // 共线
return (val > 0) ? 1 : -1;
}
bool cross_checker::Point::onSegment(const Point& p, const Point& q, const Point& r)
{
return q.x <= std::max(p.x, r.x) && q.x >= std::min(p.x, r.x) &&
q.y <= std::max(p.y, r.y) && q.y >= std::min(p.y, r.y);
}
bool cross_checker::Line::intersect(const Line& other)
{
const int o1 = Point::orientation(startPoint, endPoint, other.startPoint);
const int o2 = Point::orientation(startPoint, endPoint, other.endPoint);
const int o3 = Point::orientation(other.startPoint, other.endPoint, startPoint);
const int o4 = Point::orientation(other.startPoint, other.endPoint, endPoint);
// 普通情况:跨立实验
if (o1 != o2 && o3 != o4)
{
return true;
}
// 特殊情况:共线
if (o1 == 0 && Point::onSegment(startPoint, other.startPoint, endPoint))
{
return true;
}
if (o2 == 0 && Point::onSegment(startPoint, other.endPoint, endPoint))
{
return true;
}
if (o3 == 0 && Point::onSegment(other.startPoint, startPoint, other.endPoint))
{
return true;
}
if (o4 == 0 && Point::onSegment(other.startPoint, endPoint, other.endPoint))
{
return true;
}
return false;
}

View File

@@ -0,0 +1,10 @@
enable_testing()
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} TEST_SRC)
add_executable(
cross-checker-tests
${TEST_SRC}
)
target_link_libraries(cross-checker-tests GTest::gtest_main libcross-checker)

View File

@@ -0,0 +1,37 @@
#include <cross-checker.h>
#include <gtest/gtest.h>
TEST(SmokeTest, Test1)
{
cross_checker::Line line1(cross_checker::Point(0, 0), cross_checker::Point(1, 1));
cross_checker::Line line2(cross_checker::Point(0, 1), cross_checker::Point(1, 0));
ASSERT_TRUE(line1.intersect(line2));
}
TEST(SmokeTest, Test2)
{
cross_checker::Line line1(cross_checker::Point(0, 0), cross_checker::Point(1, 1));
cross_checker::Line line2(cross_checker::Point(2, 2), cross_checker::Point(3, 3));
ASSERT_FALSE(line1.intersect(line2));
}
TEST(SmokeTest, Test3)
{
cross_checker::Line line1(cross_checker::Point(0, 0), cross_checker::Point(1, 1));
cross_checker::Line line2(cross_checker::Point(1, 1), cross_checker::Point(2, 2));
ASSERT_TRUE(line1.intersect(line2));
}
TEST(SmokeTest, Test4)
{
cross_checker::Line line1(cross_checker::Point(0, 0), cross_checker::Point(1, 1));
cross_checker::Line line2(cross_checker::Point(2, 2), cross_checker::Point(3, 3));
ASSERT_FALSE(line1.intersect(line2));
}
TEST(SmokeTest, Test5)
{
cross_checker::Line line1(cross_checker::Point(0, 0), cross_checker::Point(2, 2));
cross_checker::Line line2(cross_checker::Point(1, 1), cross_checker::Point(3, 3));
ASSERT_TRUE(line1.intersect(line2));
}

View File

@@ -61,7 +61,7 @@ void loop() { RUN_ALL_TESTS(); }
GTEST_API_ int _tmain(int argc, TCHAR** argv) { GTEST_API_ int _tmain(int argc, TCHAR** argv) {
#else #else
GTEST_API_ int main(const int argc, const char** argv) { GTEST_API_ int main(int argc, char** argv) {
#endif // GTEST_OS_WINDOWS_MOBILE #endif // GTEST_OS_WINDOWS_MOBILE
std::cout << "Running main() from gmock_main.cc\n"; std::cout << "Running main() from gmock_main.cc\n";
// Since Google Mock depends on Google Test, InitGoogleMock() is // Since Google Mock depends on Google Test, InitGoogleMock() is