Compare commits
7 Commits
992103fd7b
...
master
Author | SHA1 | Date | |
---|---|---|---|
2b67094dcf | |||
5948001ce9 | |||
7b14919dac | |||
d2483eb095 | |||
3bfb4dde2e | |||
a4624b477f | |||
651bc79d2e |
@@ -1,8 +1,10 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(plct_lab)
|
||||
project(plct-lab)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
add_subdirectory(third-party/googletest-1.17.0)
|
||||
|
||||
add_subdirectory(mixplus)
|
||||
add_subdirectory(counter)
|
||||
add_subdirectory(cross-checker)
|
18
README.md
Normal file
18
README.md
Normal 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
11
counter/CMakeLists.txt
Normal 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
16
counter/include/counter.h
Normal 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
21
counter/main.cpp
Normal 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
34
counter/src/counter.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
10
counter/tests/CMakeLists.txt
Normal file
10
counter/tests/CMakeLists.txt
Normal 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)
|
0
counter/tests/smoke-tests.cpp
Normal file
0
counter/tests/smoke-tests.cpp
Normal file
11
cross-checker/CMakeLists.txt
Normal file
11
cross-checker/CMakeLists.txt
Normal 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)
|
38
cross-checker/include/cross-checker.h
Normal file
38
cross-checker/include/cross-checker.h
Normal 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
24
cross-checker/main.cpp
Normal 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;
|
||||
}
|
||||
}
|
58
cross-checker/src/cross-checker.cpp
Normal file
58
cross-checker/src/cross-checker.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
10
cross-checker/tests/CMakeLists.txt
Normal file
10
cross-checker/tests/CMakeLists.txt
Normal 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)
|
37
cross-checker/tests/smoke-tests.cpp
Normal file
37
cross-checker/tests/smoke-tests.cpp
Normal 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));
|
||||
}
|
@@ -61,7 +61,7 @@ void loop() { RUN_ALL_TESTS(); }
|
||||
|
||||
GTEST_API_ int _tmain(int argc, TCHAR** argv) {
|
||||
#else
|
||||
GTEST_API_ int main(const int argc, const char** argv) {
|
||||
GTEST_API_ int main(int argc, char** argv) {
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
std::cout << "Running main() from gmock_main.cc\n";
|
||||
// Since Google Mock depends on Google Test, InitGoogleMock() is
|
||||
|
Reference in New Issue
Block a user