【算法 | 实验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;
}

相关文章
|
24天前
|
存储 算法 Cloud Native
C++ bcrypt算法 字符串加密,亲测有效
C++ bcrypt算法 字符串加密,亲测有效
|
4天前
|
存储 算法 Java
Java数据结构与算法:用于高效地存储和检索字符串数据集
Java数据结构与算法:用于高效地存储和检索字符串数据集
|
6天前
|
算法 Java
Java数据结构与算法:字符串匹配算法之暴力匹配
Java数据结构与算法:字符串匹配算法之暴力匹配
|
6天前
|
算法 Java
Java数据结构与算法:字符串匹配算法之KMP算法
Java数据结构与算法:字符串匹配算法之KMP算法
|
17天前
|
算法
【经典LeetCode算法题目专栏分类】【第8期】滑动窗口:最小覆盖子串、字符串排列、找所有字母异位词、 最长无重复子串
【经典LeetCode算法题目专栏分类】【第8期】滑动窗口:最小覆盖子串、字符串排列、找所有字母异位词、 最长无重复子串
|
17天前
|
算法
【经典LeetCode算法题目专栏分类】【第6期】二分查找系列:x的平方根、有效完全平方数、搜索二位矩阵、寻找旋转排序数组最小值
【经典LeetCode算法题目专栏分类】【第6期】二分查找系列:x的平方根、有效完全平方数、搜索二位矩阵、寻找旋转排序数组最小值
|
17天前
|
算法
【经典LeetCode算法题目专栏分类】【第4期】BFS广度优先算法:单词接龙、最小基因变化、二进制矩阵中的最短路径
【经典LeetCode算法题目专栏分类】【第4期】BFS广度优先算法:单词接龙、最小基因变化、二进制矩阵中的最短路径
|
21天前
|
存储 算法 数据挖掘
LeetCode 题目 43:字符串相乘 多种算法分析对比 【python】
LeetCode 题目 43:字符串相乘 多种算法分析对比 【python】
|
24天前
|
算法
数据结构和算法——散列函数的构造方法(直接定址法、除留余数法、数字分析法、折叠法、平方取中法、ASCII码加和法、前三字符移位法)
数据结构和算法——散列函数的构造方法(直接定址法、除留余数法、数字分析法、折叠法、平方取中法、ASCII码加和法、前三字符移位法)
13 0
|
1天前
|
算法 安全 数据库
基于结点电压法的配电网状态估计算法matlab仿真
**摘要** 该程序实现了基于结点电压法的配电网状态估计算法,旨在提升数据的准确性和可靠性。在MATLAB2022a中运行,显示了状态估计过程中的电压和相位估计值,以及误差随迭代变化的图表。算法通过迭代计算雅可比矩阵,结合基尔霍夫定律解决线性方程组,估算网络节点电压。状态估计过程中应用了高斯-牛顿或莱文贝格-马夸尔特法,处理量测数据并考虑约束条件,以提高估计精度。程序结果以图形形式展示电压幅值和角度估计的比较,以及估计误差的演变,体现了算法在处理配电网状态估计问题的有效性。