首页 > 试题广场 >

字符串匹配

[编程题]字符串匹配
  • 热度指数:646 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
读入数据string[ ],然后读入一个短字符串。要求查找string[ ]中和短字符串的所有匹配,输出行号、匹配字符串。匹配时不区分大小写,并且可以有一个用中括号表示的模式匹配。如“aa[123]bb”,就是说aa1bb、aa2bb、aa3bb都算匹配。

输入描述:
输入有多组数据。
每组数据第一行输入n(1<=n<=1000),从第二行开始输入n个字符串(不含空格),接下来输入一个匹配字符串。


输出描述:
输出匹配到的字符串的行号和该字符串(匹配时不区分大小写)。
示例1

输入

4
Aab
a2B
ab
ABB
a[a2b]b

输出

1 Aab
2 a2B
4 ABB


#include <iostream> #include <algorithm> #include <queue> #include <stack> #include <vector> #include <map> #include <set> #include <stdio.h> #include <string.h> #include <math.h> using namespace std; const int CH = 36, N = 50007; struct AC {     struct Node {         Node *ch[CH];         bool end;         void init() {             memset(ch, (int)NULL, sizeof(ch));             end = false;         }     };     Node *root, *que[N];     Node a[N];     int p;     Node* getNewNode() {         a[p].init();         return &a[p ++];     }     int getindex(char ch) {         if('0' <= ch && ch <= '9') return ch - '0';         else return ch - 'a' + 10;     }     void init() {         p = 0;         root = getNewNode();     }     void insert(Node *cur, char *s, bool del) {         int index;         while(*s != '\0') {             if(*s == '[') {                 while(*(++ s) != ']') insert(cur, s, true);                 break;             } else {                 index = getindex(*(s ++));                 if(cur -> ch[index] == NULL) {                     cur -> ch[index] = getNewNode();                 }                 cur = cur -> ch[index];                 if(del) {                     while(*s != ']') s ++;                     s ++;                     del = false;                 }             }         }         if(*s == '\0') cur -> end = true;      }     bool run(char *s) {         Node *cur = root;         int index;         while(*s != '\0' && cur) {             index = getindex(*(s ++));             cur = cur -> ch[index];         }         return cur && cur -> end && *s == '\0';     } } ac; const int maxn = 1007; string instr, a[maxn], ans[maxn]; char *s; int main() {     freopen("input.txt", "r", stdin);     int i, j, n;     while(~scanf("%d", &n)) {         for(i = 1; i <= n; i ++) {             cin >> a[i];             ans[i] = a[i];             transform(a[i].begin(), a[i].end(), a[i].begin(), ::tolower);         }         cin >> instr;         transform(instr.begin(), instr.end(), instr.begin(), ::tolower);         s = (char *) instr.c_str();         ac.init();         ac.insert(ac.root, s, false);         for(i = 1; i <= n; i ++) {             if(ac.run((char *) a[i].c_str())) {                 cout << i << " " << ans[i] << endl;             }         }     }     return 0; }
//字典树一发入魂! //楼上的 悟空 是我的小伙伴哦O(∩_∩)O~
编辑于 2017-10-17 21:08:53 回复(0)
#include<iostream>
#include<string>
using namespace std;
struct node {
	int line;
	string data;
}Arr[1010];

void toLow(string &str) {
	for (int i = 0; i < str.size(); i++) {
		if (str[i] <= 'Z' && str[i] >= 'A') {
			str[i] += ('a' - 'A');
		}
	}
}

bool judge(string str, string regular) {
	toLow(str);
	toLow(regular);
	int i, j;
	string tmp;
	for (i = 0,j = 0; i < str.size() && j < regular.size(); i++,j++) {
		if (str[i] == regular[j]) continue;
		// 不相等
		if (regular[j] != '[') {
			return false;
		}
		else {
			j++;
			for (; regular[j] != ']'; j++) {
				tmp += regular[j];
			}
			if (tmp.find(str[i]) == -1) {
				return false;
			}
		}
	}
	if (i != str.size() || j != regular.size()) {
		return false;
	}
	return true;
}
int main() {
	int n;
	while (cin >> n) {
		for (int i = 0; i < n; i++) {
			cin >> Arr[i].data;
			Arr[i].line = i + 1;
		}
		string regular;
		cin >> regular;
		for (int i = 0; i < n; i++) {
			if (judge(Arr[i].data, regular)) {
				cout << Arr[i].line << " " << Arr[i].data << endl;
			}
		}
	}	
	return 0;
}

发表于 2020-10-08 15:08:59 回复(0)
//AC代码:
#include<string>
#include<iostream>
#include<vector>
#include<map>
#include<stdio.h>
using namespace std;
map<int,string> res;
bool equals(string a,string b){
    if(a.length()!=b.length()) return false;
    for(int i=0;i<a.length();i++)
        if('a'<=a[i]&&a[i]<='z'){
            int tmp=a[i]-'a';
            if((int)(b[i]-'a')!=tmp&&(int)(b[i]-'A')!=tmp)
                return false;
        }else if('A'<=a[i]&&a[i]<='Z'){
            int tmp=a[i]-'A';
            if((int)(b[i]-'a')!=tmp&&(int)(b[i]-'A')!=tmp)
                return false;
        }else{
            if(a[i]!=b[i]) return false;
        }
    return true;
}
string x;
void dfs(int index,string step,vector<string>&dict){
    if(index>=x.length()){
        for(int j=0;j<dict.size();j++)
            if(equals(step,dict[j]))
                res[j+1]=dict[j];
    }else{
        int i;
        if(x[index]!='[')
            dfs(index+1,step+x[index],dict);
        else{
            int j,k;
            for(j=index;x[j]!=']';j++);
            for(k=index+1;k<j;k++)
                dfs(j+1,step+x[k],dict);
        }
    }
}
int main(){
    int n,i,j,k;
    //freopen("input.txt","r",stdin);
    while(scanf("%d",&n)!=EOF){
        vector<string> dict(n);
        for(i=0;i<n;i++) cin>>dict[i];
        cin>>x;
        res.clear();
        vector<string> m; 
        dfs(0,"",dict);
        map<int,string>::iterator it;
        for(it=res.begin();it!=res.end();it++)
            printf("%d %s\n",it->first,(it->second).c_str());
    }
}//用dfs把所有情况搜索一遍,然后在给出的dict中匹配
 //楼下还有字典树的解法哟~
 //楼下的 MyIsBoy 是我的小伙伴O(∩_∩)O~

编辑于 2017-10-18 07:44:11 回复(1)
//写这道题是因为王道的《机试指南》字符串匹配的最后一道练习题,给大家看一下我的错误解法,用KMP算法,时间复杂度过高了(甚至只能跑n=2的情况,再大就跑不了),希望有缘人看到能帮我修改一下,万分感谢
#include<iostream>
#include<string>
#include<vector>

using namespace std;

int NextTabel[100];

void CreatTabel(string s)
{
    int n = s.length();
    int i = -1, j = 0;
    NextTabel[0] = -1;
    while (j<n)
    {
        if (i == -1 || s[i] == s[j])
        {
            i++; j++;
            NextTabel[j] = i;
        }
        else
            i = NextTabel[i];
    }
}

bool KMP(string a, string b)
{
    int index1 = a.find('[');
    int index2 = a.find(']');
    CreatTabel(b);
    int m = a.length(), n = b.length();
    int i = 0, j = 0;
    bool flag = false;
    while (i<m&&j<n)
    {
        if(i==index1)
        {
            for (int k = index1 + 1; k < index2;++k)
            {
                if (a[k] == b[j])
                {
                    j++;
                    i = index2 + 1;
                    flag = true;
                }
            }
        }
        else if (j == -1 || a[i] == b[j])
        {
            i++;
            j++;
        }
        else
            j = NextTabel[j];
    }
    if (flag&&j == n)
        return true;
    else
        return false;
}

int main()
{
    int n;
    cin >> n;
    int number = 0;
    vector<string> p(n);
    for (int i = 0; i < n; i++)
    {
        cin >> p[i];
    }
    for (int i = 0; i < n; i++)
    {
    }
    string s;
    cin >> s;
    for (int i = 0; i < n; ++i)
    {
        if (KMP(s, p[i]))
            cout <<i + 1 << " " << p[i] << endl;
    }
    return 0;

}

发表于 2022-07-13 01:09:33 回复(1)
有库用为什么不用,直接用正则表达式还不是美滋滋(逃
#include <iostream>
#include <string>
#include <regex>
#include <vector>
using namespace std;

int main() {
    vector<string> in;
    ios::sync_with_stdio(false); cin.tie(0);
    for (int n; cin >> n;) {
        in.resize(n + 1);
        for (int i = 0; i <= n; ++i) cin >> in[i];
        regex re(in.back(), regex_constants::ECMAScript | regex_constants::icase);
        for (int i = 0; i < n; ++i) {
            if (regex_match(in[i], re)) cout << i + 1 << ' ' << in[i] << '\n';
        }
    }
}
发表于 2019-08-19 19:42:41 回复(0)
import java.util.Scanner; import java.util.regex.Pattern; public class Main{    public static void main(String [] args){         Scanner sc=new Scanner(System.in);         int n=sc.nextInt();         String[] s=new String[n];         for(int i=0;i<n;i++)             s[i]=sc.next();         String patt=sc.next();         Pattern pattern=Pattern.compile(patt, Pattern.CASE_INSENSITIVE|Pattern.UNICODE_CASE);                  for(int i=0;i<s.length;i++){             if((pattern.matcher(s[i]))!=null){                 System.out.println(i+" "+s[i]);             }         }     } } 
运行出错,哪位大神看看
发表于 2017-10-17 17:48:27 回复(0)