【算法 | 实验18】在字符矩阵中查找给定字符串的所有匹配项

简介: 题目描述题目在字符矩阵中查找给定字符串的所有匹配项给定一个M×N字符矩阵,以及一个字符串S,找到在矩阵中所有可能的连续字符组成的S的次数。所谓的连续字符,是指一个字符可以和位于其上下左右,左上左下,右上右下8个方向的字符组成字符串。用回溯法求解。

题目描述

题目

在字符矩阵中查找给定字符串的所有匹配项

给定一个M×N字符矩阵,以及一个字符串S,找到在矩阵中所有可能的连续字符组成的S的次数。所谓的连续字符,是指一个字符可以和位于其上下左右,左上左下,右上右下8个方向的字符组成字符串。用回溯法求解。

输入描述

输入整数t表示测试用例个数

每个测试用例,输入整数M,N,表示矩阵的行数和列数。

接下来输入M行,每行输入N列个字符

第M+1行输入一个需要在矩阵中查找的字符串S

输出描述

输出t行,每行表示第t个测试用例中矩阵中字符串出现的次数

样例输入

1

5 5

D E M X B

A O E P E

D D C O D

E B E D S

C P Y E N

CODE

样例输出

8

样例解析,有一个测试样例,给定一个5行5列字符矩阵,要查找的字符串是CODE

输出为8表示矩阵中总共包含8个"CODE",如下所示,括号内为字符对应的行和列。

‘C’(2, 2) ‘O’(1, 1) ‘D’(0, 0) ‘E’(0, 1)

‘C’(2, 2) ‘O’(1, 1) ‘D’(2, 0) ‘E’(3, 0)

‘C’(2, 2) ‘O’(1, 1) ‘D’(2, 1) ‘E’(1, 2)

‘C’(2, 2) ‘O’(1, 1) ‘D’(2, 1) ‘E’(3, 0)

‘C’(2, 2) ‘O’(1, 1) ‘D’(2, 1) ‘E’(3, 2)

‘C’(2, 2) ‘O’(2, 3) ‘D’(2, 4) ‘E’(1, 4)

‘C’(2, 2) ‘O’(2, 3) ‘D’(3, 3) ‘E’(3, 2)

‘C’(2, 2) ‘O’(2, 3) ‘D’(3, 3) ‘E’(4, 3)

思路分析

和经典的回溯法走迷宫很像,比较不同的是:

1、有 8 个行走方向

2、需要统计能匹配目标字符串的路径的数量

关于 8 个行走方向,我差点就要上 8 个if了,好在及时想到了可以使用循环。

屏幕截图 2023-12-28 163101.png

fb942c0fb91242febc5442de574447b9.png

bug记录:“error: ‘>>’ should be ‘> >’ within a nested template argument list”

中文翻译:“错误:”>>“在嵌套模板参数列表中应为”> >”

// 错误代码
vector<vector<char>>
// 修改方案:在两个尖括号中加个空格
vector<vector<char> >

原因:在使用C++11之前标准的编译器将">>“视为移位符号,导致编译错误

参考https://blog.csdn.net/yiti8689/article/details/108134804

代码

OJ成功通过了

#include<iostream>
#include<cstdio>
#include<vector>
#include<string>
using namespace std;
//判断i, j是否在矩阵内 
bool inside(int i, int j, int m, int n){
  if(0 <= i && i < m && 0 <= j && j < n){
    return true;
  }
  return false;
}
// 回溯实现
// 参数,i,j为当前位置;len为已成功匹配的字符个数;s为目标字符串; 
int hui_su(vector<vector<char> > a, int i, int j, int m, int n, int len, string s){
  if(a[i][j] != s[len]){
    return 0;
  }
  else {
    len++;
    if(s.length() == len){
      return 1;
    }
  }
  //向8个方向搜索 
  int count = 0;
  for(int x = -1; x <= 1; x++){
    for(int y = -1; y <= 1; y++){
      if(x == 0 && y == 0){
        continue;
      }
      if(inside(i+x, j+y, m, n)){
        count += hui_su(a, i+x, j+y, m, n, len, s);
      }
    }
  }
  return count;
}
int main(){
  int t;  //测试用例个数
  cin >> t; 
  // 输入
  for(int k = 0; k < t; k++){
    int m, n;  //矩阵的大小
    string s;  //目标字符串 
    cin >> m >> n;
    vector<vector<char> > a(m, vector<char>(n));  //矩阵
    for(int i = 0; i < m; i++){
      for(int j = 0; j < n; j++){
        cin >> a[i][j];
      }
    } 
    cin >> s;
    int count = 0;
    for(int i = 0; i < m; i++){
      for(int j = 0; j < n; j++){
        count += hui_su(a, i, j, m, n, 0, s);
      }
    }
    cout << count;
  } 
  return 0;
}

相关文章
|
2月前
|
算法 前端开发 数据处理
小白学python-深入解析一位字符判定算法
小白学python-深入解析一位字符判定算法
53 0
|
2月前
|
算法
两个字符串匹配出最长公共子序列算法
本文介绍了最长公共子序列(LCS)问题的算法实现,通过动态规划方法求解两个字符串的最长公共子序列,并提供了具体的编程实现细节和示例。
97 1
两个字符串匹配出最长公共子序列算法
|
2月前
|
并行计算 算法 IDE
【灵码助力Cuda算法分析】分析共享内存的矩阵乘法优化
本文介绍了如何利用通义灵码在Visual Studio 2022中对基于CUDA的共享内存矩阵乘法优化代码进行深入分析。文章从整体程序结构入手,逐步深入到线程调度、矩阵分块、循环展开等关键细节,最后通过带入具体值的方式进一步解析复杂循环逻辑,展示了通义灵码在辅助理解和优化CUDA编程中的强大功能。
|
2月前
|
机器学习/深度学习 算法 搜索推荐
django调用矩阵分解推荐算法模型做推荐系统
django调用矩阵分解推荐算法模型做推荐系统
43 4
|
2月前
|
算法 搜索推荐 Java
java 后端 使用 Graphics2D 制作海报,画echarts图,带工具类,各种细节:如头像切割成圆形,文字换行算法(完美实验success),解决画上文字、图片后不清晰问题
这篇文章介绍了如何使用Java后端技术,结合Graphics2D和Echarts等工具,生成包含个性化信息和图表的海报,并提供了详细的代码实现和GitHub项目链接。
147 0
java 后端 使用 Graphics2D 制作海报,画echarts图,带工具类,各种细节:如头像切割成圆形,文字换行算法(完美实验success),解决画上文字、图片后不清晰问题
|
2月前
|
存储 算法
动态规划算法学习一:DP的重要知识点、矩阵连乘算法
这篇文章是关于动态规划算法中矩阵连乘问题的详解,包括问题描述、最优子结构、重叠子问题、递归方法、备忘录方法和动态规划算法设计的步骤。
157 0
|
2月前
|
算法
计科一二班算法数据结构实验9答案
计科一二班算法数据结构实验9答案
19 0
|
4月前
|
算法 Java
掌握算法学习之字符串经典用法
文章总结了字符串在算法领域的经典用法,特别是通过双指针法来实现字符串的反转操作,并提供了LeetCode上相关题目的Java代码实现,强调了掌握这些技巧对于提升算法思维的重要性。
|
4月前
|
机器学习/深度学习 算法 Java
算法设计(动态规划应用实验报告)实现基于贪婪技术思想的Prim算法、Dijkstra算法
这篇文章介绍了基于贪婪技术思想的Prim算法和Dijkstra算法,包括它们的伪代码描述、Java源代码实现、时间效率分析,并展示了算法的测试用例结果,使读者对贪婪技术及其应用有了更深入的理解。
算法设计(动态规划应用实验报告)实现基于贪婪技术思想的Prim算法、Dijkstra算法
|
4月前
|
算法 Java 测试技术
算法设计(动态规划实验报告) 基于动态规划的背包问题、Warshall算法和Floyd算法
这篇文章介绍了基于动态规划法的三种算法:解决背包问题的递归和自底向上实现、Warshall算法和Floyd算法,并提供了它们的伪代码、Java源代码实现以及时间效率分析。
算法设计(动态规划实验报告) 基于动态规划的背包问题、Warshall算法和Floyd算法