Brute Force算法介绍及C++实现

字符串的模式匹配操作可以通过Brute Force算法来实现。字符串匹配操作即是查看S串(目标串或主串)中是否含有T串(模式串或子串),如果在主串中查找到了子串,则模式匹配成功,返回模式串中的第一个字符在主串中的位置;如果未找到,则模式匹配失败,返回-1。

Brute Force算法,即暴风算法,是简单的模式匹配算法,其思想是将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相等,则继续比较S的第二个字符和T的第二个字符;若不相等,则比较S的第二个字符和T的第一个字符,依次比较下去,直到得出最后的匹配结果。Brute Force算法简单,易于实现;进行了回溯,效率不高。KMP算法是Brute Force的一种改进算法。

以下是测试code:

#include <string>
#include <vector>
#include <opencv2/opencv.hpp>
#include "common.hpp"

// ============================ Brute Force ================================
typedef std::tuple<int, int> brute_force_result; // <status, pos>

int brute_force(const std::string& str, const std::string& sub, brute_force_result& result)
{
	std::get<0>(result) = -1;
	std::get<1>(result) = -1;

	int length_str = str.length(), length_sub = sub.length();

	if (length_str < length_sub) return 0;

	for (int i = 0; i < length_str - length_sub + 1; ++i) {
		int count{ 0 };

		for (int j = 0; j < length_sub; ++j) {
			const char& c1 = str.at(i + count);
			const char& c2 = sub.at(j);

			if (c1 == c2) ++count;
			else break;
		}

		if (count == length_sub) {
			std::get<0>(result) = 0;
			std::get<1>(result) = i;
		}
	}

	return 0;
}

int test_brute_force_string_match()
{
	const std::string str{ "abcdABCD EFaadfk32!@#34flasf dafe" };
	const std::vector<std::string> sub{ "abcde", "ABCD EF", "fe", "!@#", "asf dafe", "afea"};

	for (const auto& val : sub) {
		fbc::brute_force_result result;

		fbc::brute_force(str, val, result);

		fprintf(stdout, "string match result: status: %d, pos: %d\n",
			std::get<0>(result), std::get<1>(result));
	}

	return 0;
}
执行结果如下:


GitHub:  https://github.com/fengbingchun/NN_Test 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Informed-RRT*是一种基于Rapidly-exploring Random Tree (RRT)算法的路径规划算法,它可以在未知环境中规划出可行路径。该算法通过使用启发信息来改进搜索效率,从而使得搜索结果更快收敛到最优解。下面是使用C语言实现Informed-RRT*算法的一些基本步骤: 1. 定义RRT结构体 首先,我们需要定义一个结构体描述RRT的节点。RRT节点包括一个状态和指向其父节点的指针。 ```c typedef struct rrt_node { double state[2]; struct rrt_node *parent; } RRTNode; ``` 2. 初始化起点和终点 接下来,我们需要初始化起点和终点。在这个过程中,我们需要设置起点的指向空指针,因为它没有父节点。 ```c RRTNode *initialize_start_and_goal(double start[2], double goal[2]) { RRTNode *start_node = malloc(sizeof(RRTNode)); RRTNode *goal_node = malloc(sizeof(RRTNode)); memcpy(start_node->state, start, sizeof(double) * 2); memcpy(goal_node->state, goal, sizeof(double) * 2); start_node->parent = NULL; goal_node->parent = NULL; return start_node; } ``` 3. 定义随机采样函数 接下来,我们需要定义一个随机采样函数,该函数返回一个随机状态。在Informed-RRT*算法中,我们需要利用启发信息来指导随机采样。因此,我们需要传入一个最优解的距离,以便在搜索中使用。 ```c void random_sample(double sample[2], double goal[2], double radius) { double dx = goal[0] - sample[0]; double dy = goal[1] - sample[1]; double distance = sqrt(dx * dx + dy * dy); if (distance < radius) { memcpy(sample, goal, sizeof(double) * 2); return; } double angle = atan2(dy, dx); double r = radius * (double)rand() / RAND_MAX; sample[0] += r * cos(angle); sample[1] += r * sin(angle); } ``` 4. 定义距离函数 在Informed-RRT*算法中,我们需要使用两个距离函数:欧几里得距离和启发距离。欧几里得距离用于计算两个状态之间的实际距离,而启发距离用于指导随机采样。 ```c double euclidean_distance(double *state1, double *state2) { double dx = state1[0] - state2[0]; double dy = state1[1] - state2[1]; return sqrt(dx * dx + dy * dy); } double heuristic_distance(double *state, double *goal, double radius) { double dx = goal[0] - state[0]; double dy = goal[1] - state[1]; double distance = sqrt(dx * dx + dy * dy); return fmin(distance, radius); } ``` 5. 定义最近邻函数 在RRT算法中,我们需要找到最近邻节点。为了提高搜索效率,我们可以使用k-d树来存储RRT树。在这里,我们使用Brute-force算法找到最近邻节点。 ```c RRTNode *nearest_neighbor(RRTNode *root, double state[2]) { RRTNode *nearest = root; double min_distance = euclidean_distance(root->state, state); RRTNode *current = root; while (current != NULL) { double distance = euclidean_distance(current->state, state); if (distance < min_distance) { nearest = current; min_distance = distance; } current = current->parent; } return nearest; } ``` 6. 定义可达函数 在RRT算法中,我们需要判断两个状态之间是否可达。在这里,我们使用直线路径来判断两个状态之间是否可达。 ```c int is_reachable(double *state1, double *state2, double step_size) { double distance = euclidean_distance(state1, state2); int n = (int)ceil(distance / step_size); for (int i = 1; i <= n; i++) { double ratio = (double)i / n; double x = (1 - ratio) * state1[0] + ratio * state2[0]; double y = (1 - ratio) * state1[1] + ratio * state2[1]; if (!is_valid(x, y)) { return 0; } } return 1; } ``` 7. 定义插入节点函数 在RRT算法中,我们需要插入新节点。在Informed-RRT*算法中,我们需要使用启发距离来判断新节点是否足够优秀。 ```c RRTNode *insert_node(RRTNode *nearest, double *sample, double step_size, double goal[2], double radius) { double distance = euclidean_distance(nearest->state, sample); if (distance > step_size) { double ratio = step_size / distance; sample[0] = (1 - ratio) * nearest->state[0] + ratio * sample[0]; sample[1] = (1 - ratio) * nearest->state[1] + ratio * sample[1]; } if (!is_reachable(nearest->state, sample, step_size)) { return NULL; } RRTNode *new_node = malloc(sizeof(RRTNode)); memcpy(new_node->state, sample, sizeof(double) * 2); new_node->parent = nearest; double heuristic = heuristic_distance(sample, goal, radius); RRTNode *current = nearest; while (current != NULL) { double distance = euclidean_distance(current->state, sample); if (distance > step_size) { break; } double current_heuristic = heuristic_distance(current->state, goal, radius); double cost = current->parent == NULL ? distance : current->parent->state[2] + distance; if (cost + current_heuristic < heuristic) { heuristic = cost + current_heuristic; new_node->parent = current; } current = current->parent; } new_node->state[2] = new_node->parent == NULL ? distance : new_node->parent->state[2] + distance; return new_node; } ``` 8. 定义路径生成函数 最后,我们需要定义一个函数来生成路径。在Informed-RRT*算法中,我们需要使用启发距离来指导搜索。 ```c RRTNode *get_best_node(RRTNode *root, double goal[2], double radius) { RRTNode *best = NULL; double best_cost = INFINITY; queue<RRTNode *> q; q.push(root); while (!q.empty()) { RRTNode *node = q.front(); q.pop(); double cost = node->state[2] + heuristic_distance(node->state, goal, radius); if (cost < best_cost) { best_cost = cost; best = node; } for (int i = 0; i < node->children.size(); i++) { q.push(node->children[i]); } } return best; } void generate_path(RRTNode *start_node, RRTNode *best_node, vector<double> &path) { RRTNode *current = best_node; while (current != start_node) { path.push_back(current->state[0]); path.push_back(current->state[1]); current = current->parent; } path.push_back(start_node->state[0]); path.push_back(start_node->state[1]); reverse(path.begin(), path.end()); } ``` 完整代码如下:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值