码迷,mamicode.com
首页 > 其他好文 > 详细

字符串

时间:2021-03-04 13:24:30      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:信息   部分   sam   bin   字符串长度   core   add   flag   other   

1.字符串

  1. string 的定义
  2. string 的初始化
  3. string 的长度
  4. string 的元素的访问
    • 数组
    • 迭代器
  5. 元素的操作
    • insert()
    • erase()
    • clear()
  6. 运算符
    • 连接 +
    • 比较运算符
    • 判断是否相等
  7. 常用函数
    • find()
    • substr()
/**
 * @author: Qiuyue Zhang
 * @date: 2021/2/10 14:14
 * @description: string的基础
 */
#include <iostream>
#include <cstdio>
#include <string>

using namespace std;

int main(){
    //string str;
    string str = "hello world";
    cout<<str<<endl;
    //size()
    int n = str.size();
    printf("%d\n", n);
    // 数组访问
    for(int i = 0; i < str.size(); ++i){
        printf("%c", str[i]);
    }

    printf("\n");
    printf("the 7th element of str is: c\n", str[6]);
    //迭代器访问
    for(auto it = str.begin(); it != str.end(); ++it){
        printf("%c", *it);
    }

    printf("\n");
    //在末尾插入字符
    str.insert(str.size(), " end world");
    cout << str << endl;
    // 清除[0,12)下标的字符
    str.erase(0, 12);
    cout << str << endl;
    //在0下标的位置插入
    str.insert(0, "how to ");
    cout << str << endl;
    //从7下标的位置开始擦除
    str.erase(7);
    cout << str << endl;
    //清空字符串
    str.clear();
    cout << str << endl;

    str = "hello world";
    int found = str.find("world");
    if(found != string::npos){
        printf("‘world‘ found at: %d\n", found);
    }

    found = str.find(‘l‘);
    if(found != string::npos){
        printf("‘.‘ not founded");
    }

    string str1 = "We think in generalities, but we live in details";
    string str2 = str1.substr(3,5);
    cout << str2 << endl;
    
    return 0;
}

2.字符串处理

KY18 特殊乘法

题目描述

写个算法,对2个小于1000000000的输入,求结果。 特殊乘法举例:123 * 45 = 1*4 +1*5 +2*4 +2*5 +3*4+3*5

输入描述:

两个小于1000000000的数

输出描述:

输入可能有多组数据,对于每一组数据,输出Input中的两个数按照题目要求的方法进行运算后得到的结果。

输入

123 45

输出

54

代码

#include<iostream>
#include<cstdio>
using namespace std;

int main()
{
    string str1, str2;
    while(cin >> str1 >> str2)
    {
        int sum = 0;
        for(int i = 0; i < str1.length(); ++i)
        {
            for(int j = 0; j < str2.length(); ++j)
            {
                sum += (str1[i]-‘0‘)*(str2[j]-‘0‘);
            }
        }

        cout << sum << endl;
    }

    return 0;
}

KY33 密码翻译

题目描述

在情报传递过程中,为了防止情报被截获,往往需要对情报用一定的方式加密,简单的加密算法虽然不足以完全避免情报被破译,但仍然能防止情报被轻易的识别。我们给出一种最简的的加密方法,对给定的一个字符串,把其中从a-y,A-Y的字母用其后继字母替代,把z和Z用a和A替代,则可得到一个简单的加密字符串。

输入描述:

读取这一行字符串,每个字符串长度小于80个字符。

输出描述:

对于每组数据,输出每行字符串的加密字符串。

输入

1
Hello! How are you!

输出

Ifmmp! Ipx bsf zpv!

代码

#include <iostream>
#include <cstdio>
#include <string>

using namespace std;

int main(){
    string str;
    //如果直接按照string 进行输入,那么遇到空格就会停止输入。
    //使用getline()来获取一行字符串
    while (getline(cin, str)){
        for(int i = 0; i < str.size(); ++i){
            if(str[i] == ‘z‘ || str[i] == ‘Z‘){
                str[i] -= 25;
            }else if ((str[i] >= ‘A‘&& str[i] <= ‘Y‘ )||(str[i] >= ‘a‘&& str[i] <= ‘y‘ ) ){
                str[i]++;
            }
        }
        cout << str <<endl;
        return 0;
    }
}

KY90 简单密码

题目描述

Julius Caesar曾经使用过一种很简单的密码。 对于明文中的每个字符,将它用它字母表中后5位对应的字符来代替,这样就得到了密文。 比如字符A用F来代替。如下是密文和明文中字符的对应关系。 密文 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 明文 V W X Y Z A B C D E F G H I J K L M N O P Q R S T U 你的任务是对给定的密文进行解密得到明文。 你需要注意的是,密文中出现的字母都是大写字母。密文中也包括非字母的字符,对这些字符不用进行解码。

输入描述:

输入中的测试数据不超过100组。每组数据都有如下的形式,而且各组测试数据之间没有空白的行。
一组测试数据包括三部分:

  1. 起始行 :一行,包括字符串 "START"

  2. 密文:一行,给出密文,密文不为空,而且其中的字符数不超过200

  3. 结束行 : 一行,包括字符串 "END"

    在最后一组测试数据之后有一行,包括字符串 "ENDOFINPUT"。

输出描述:

对每组数据,都有一行输出,给出密文对应的明文。

输入

START
NS BFW, JAJSYX TK NRUTWYFSHJ FWJ YMJ WJXZQY TK YWNANFQ HFZXJX
END
START
N BTZQI WFYMJW GJ KNWXY NS F QNYYQJ NGJWNFS ANQQFLJ YMFS XJHTSI NS WTRJ
END
START
IFSLJW PSTBX KZQQ BJQQ YMFY HFJXFW NX RTWJ IFSLJWTZX YMFS MJ
END
ENDOFINPUT

输出

IN WAR, EVENTS OF IMPORTANCE ARE THE RESULT OF TRIVIAL CAUSES
I WOULD RATHER BE FIRST IN A LITTLE IBERIAN VILLAGE THAN SECOND IN ROME
DANGER KNOWS FULL WELL THAT CAESAR IS MORE DANGEROUS THAN HE

代码

#include <iostream>
#include <cstdio>
#include <string>

using namespace std;

int main(){
    string str;
    while(getline(cin,str)){
        if(str == "ENDOFINPUT"){
            break;
        }
        getline(cin, str);
        for(int i = 0; i < str.size(); ++i){
            if(‘A‘ <= str[i] && str[i] <= ‘Z‘){
                //求解循环平移问题,对字母进行减法操作后,再对字母个数26取模
             str[i] = (str[i]-‘A‘-5+26)%26+‘A‘;
            }
        }
        cout<< str << endl;
        getline(cin, str);
    }
    return 0;
}

KY127 统计字符

题目描述

统计一个给定字符串中指定的字符出现的次数。

输入描述:

测试输入包含若干测试用例,每个测试用例包含2行,第1行为一个长度不超过5的字符串,第2行为一个长度不超过80的字符串。注意这里的字符串包含空格,即空格也可能是要求被统计的字符之一。当读到‘#‘时输入结束,相应的结果不要输出。

输出描述:

对每个测试用例,统计第1行中字符串的每个字符在第2行字符串中出现的次数,按如下格式输出:
c0 n0
c1 n1
c2 n2
...
其中ci是第1行中第i个字符,ni是ci出现的次数。

输入

I
THIS IS A TEST
i ng
this is a long test string
#

输出

I 2
i 3
  5
n 2
g 2

代码

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>

using namespace std;

int number[128];

int main(){
    string str1, str2;
    while (getline(cin,str1)){
        if(str1 == "#"){
            break;
        }
        getline(cin, str2);
        memset(number, 0, sizeof(number));
        for(int i = 0; i < str2.size(); ++i){
            number[str2[i]]++;
        }
        for (int i = 0; i < str1.size(); ++i) {
            printf("%c %d\n", str1[i], number[str1[i]]);
        }
    }
    return 0;
}

KY113 字母统计

题目描述

输入一行字符串,计算其中A-Z大写字母出现的次数

输入描述:

案例可能有多组,每个案例输入为一行字符串。

输出描述:

对每个案例按A-Z的顺序输出其中大写字母出现的次数。

输入

DFJEIWFNQLEF0395823048+_+JDLSFJDLSJFKK

输出

A:0
B:0
C:0
D:3
E:2
F:5
G:0
H:0
I:1
J:4
K:2
L:3
M:0
N:1
O:0
P:0
Q:1
R:0
S:2
T:0
U:0
V:0
W:1
X:0
Y:0
Z:0

代码

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>

using namespace std;

int number[26];

int main(){
    string str;
    while (cin>>str){
        memset(number,0,sizeof(number));
        for (int i = 0; i < str.size(); ++i) {
            if (‘A‘ <= str[i] && str[i] <=‘Z‘){
                number[str[i] - ‘A‘]++;
            }
        }
        for(int i = 0; i < 26; ++i){
            printf("%c:%d\n",‘A‘ + i, number[i]);
        }
    }
    return 0;
}

KY45 skew数

题目描述

在 skew binary 表示中,第 k 位的值 x[k] 表示 x[k]×(2^(k+1)-1)。每个位上的可能数字是 0 或 1,最后面一个非零位可以是 2,例如,10120(skew) = 1×(2^5-1) + 0×(2^4-1) + 1×(2^3-1) + 2×(2^2-1) + 0×(2^1-1) = 31 + 0 + 7 + 6 + 0 = 44。前十个 skew 数是 0、1、2、10、11、12、20、100、101、以及 102。

输入描述:

输入包括多组数据,每组数据包含一个 skew 数。

输出描述:

对应每一组数据,输出相应的十进制形式。结果不超过 2^31-1。

输入

10120
200000000000000000000000000000
10
1000000000000000000000000000000
11
100
11111000001110000101101102000

输出

44
2147483646
3
2147483647
4
7
1041110737

代码

# include<stdio.h>
# include<string.h>
# include<math.h>

int skew(char str[])
{
    int len=strlen(str);
    int i;
    int sum=0;
    for(i=0;i<len;i++)
    {
        int num=str[i]-‘0‘;
        sum=sum+num*(pow(2,len-i)-1);
    }
    return sum;
}

int main()
{
    char str[200];
    while(scanf("%s",str)!=EOF)
    {
        printf("%d\n",skew(str));
    }
    return 0;
}

KY46 单词替换

题目描述

输入一个字符串,以回车结束(字符串长度<=100)。该字符串由若干个单词组成,单词之间用一个空格隔开,所有单词区分大小写。现需要将其中的某个单词替换成另一个单词,并输出替换之后的字符串。

输入描述:

多组数据。每组数据输入包括3行, 第1行是包含多个单词的字符串 s, 第2行是待替换的单词a,(长度<=100) 第3行是a将被替换的单词b。(长度<=100) s, a, b 最前面和最后面都没有空格。

输出描述:

每个测试数据输出只有 1 行, 将s中所有单词a替换成b之后的字符串。

输入

You want someone to help you 
You 
I

输出

I want someone to help you

代码

#include<iostream>
#include<string>
#include<vector>
#define WRA "CCCCCC III A BBB CCCCCC AAAA III CCCCCC A AAAA CCCC CCC AAAA gold white CC white A BBB AAAA"
using namespace std;

int main()
{
    string sentence;//保存句子
    string a;//被替换的单词
    string b;//用来替换的单词
    vector<string> words;//保存句子中的单词
    words.push_back("");
    getline(cin, sentence);
    cin >> a >> b;
    for(int i = 0, j = 0; i < sentence.length(); i++)
    {//将句子分割为单词,存入words中
        if(sentence[i] != ‘ ‘)
            words[j] += sentence[i];
        else
        {
            words.push_back("");
            j++;
        }

    }
    //依次将words中的单词与a做比较,若相同,则替换为b
    for(int i = 0; i < words.size(); i++)
    {
        if(words[i] == a)
            words[i] = b;
    }
    //输出结果
    for(int i = 0; i < words.size() - 1; i++)
    {
        cout << words[i] << ‘ ‘;
    }
    cout << words[words.size() - 1];

    return 0;
}

KY57 首字母大写

题目描述

对一个字符串中的所有单词,如果单词的首字母不是大写字母,则把单词的首字母变成大写字母。 在字符串中,单词之间通过空白符分隔,空白符包括:空格(‘ ‘)、制表符(‘\t‘)、回车符(‘\r‘)、换行符(‘\n‘)。

输入描述:

输入一行:待处理的字符串(长度小于100)。

输出描述:

可能有多组测试数据,对于每组数据,
输出一行:转换后的字符串。

输入

if so, you already have a google account. you can sign in on the right.

输出

If So, You Already Have A Google Account. You Can Sign In On The Right.

代码

#include<iostream>
#include<string>
using namespace std;
int main(){
    string s;
    getline(cin,s);
    for(int i=0;i<s.length();i++){
        if(i==0)
            s[i]=toupper(s[i]);
        else{
            if(s[i-1]==‘ ‘||s[i-1]==‘\t‘||s[i-1]==‘\r‘||s[i-1]==‘\n‘)
                s[i]=toupper(s[i]);
        }
    }
    cout<<s;
}

KY79 浮点数加法

题目描述

求2个浮点数相加的和。题目中输入输出中出现浮点数都有如下的形式: P1P2...Pi.Q1Q2...Qj 。对于整数部分,P1P2...Pi是一个非负整数;对于小数部分,Qj不等于0。

输入描述:

对于每组案例,每组测试数据占2行,分别是两个加数。

输出描述:

每组案例是n行,每组测试数据有一行输出是相应的和。
输出保证一定是一个小数部分不为0的浮点数

输入

0.111111111111111111111111111111
0.111111111111111111111111111111

输出

0.222222222222222222222222222222

代码

#include <iostream>
using namespace std;

string add(string sa, string sb)
{
    string result, sc, sd;
//下面是将两浮点数对齐
    int ia = sa.find(".", 0);
    int ib = sb.find(".", 0);
    sc = (ia>ib)?sa:sb;
    sd = (ia>ib)?sb:sa;
    int n = (ia>ib)?(ia-ib):(ib-ia);
    while(n--)
    {
        sd = "0"+sd;
    }
    int lenc = sc.length();
    int lend = sd.length();
    sa = (lenc>lend)?sc:sd;
    sb = (lenc>lend)?sd:sc;
    n = (lenc>lend)?(lenc-lend):(lend-lenc);
    while(n--)
    {
        sb+="0";
    }
//对对齐后的浮点数进行相加
    int carry = 0;
    for(int i = sa.length()-1; i>=0; i--)
    {
        if(sa[i]==‘.‘)
        {
            result = "."+result;
            continue;
        }
        char value = sa[i]-‘0‘+sb[i]-‘0‘+carry;
        result = char(value%10+‘0‘)+result;
        carry = value/10;
    }
    while(carry!=0)
    {
        result = char(carry%10+‘0‘)+result;
        carry/=10;
    }
    return result;
}
int main()
{
    string sa, sb;
    while(cin>>sa)
    {
        cin>>sb;
        cout<<add(sa, sb)<<endl;
    }
    return 0;
}

KY115 后缀子串排序

题目描述

对于一个字符串,将其后缀子串进行排序,例如grain 其子串有: grain rain ain in n 然后对各子串按字典顺序排序,即: ain,grain,in,n,rain

输入描述:

每个案例为一行字符串。

输出描述:

将子串排序输出

输入

grain

输出

ain
grain
in
n
rain

代码

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main(){
    string s;
    while(cin>>s){
        string a[s.size()];
        for(int i=0;i<s.size();i++){
            a[i]=s.substr(i,s.size()-i);
        }
        sort(a,a+s.size());
        for(int i=0;i<s.size();i++)cout<<a[i]<<endl;
    }
    return 0;
}

3.字符串匹配

字符串匹配问题:给出两个字符串,其中一个是文本串test(长度为\(n\)),另一个是模式串pattern(长度为\(m\)),如何判断模式串是否为文本串的一个子串?

暴力算法:将模式串和文本串逐字符比较,如果发生失配,那么就从字符串的下一个字符开始重新比较,知道完全匹配或遍历完整的文本串仍未成功。时间复杂度为\(O(mn)\)

KMP算法:模式串失配后,并不是从下一个字符开始重新匹配,而是利用已有的信息,跳过一些不可能成功匹配的位置,以便尽量减少模式串与主串的匹配次数,进而达到快速匹配的目的。时间复杂度为\(O(m+n)\)

  • 预处理,求next数组:字符串的前缀与后缀相同的最大长度
  • 发生失配后,按照next数组进行跳转,之后重新尝试匹配。

HDU Number Sequence

Problem Description

Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1], b[2], ...... , b[M] (1 <= M <= 10000, 1 <= N <= 1000000). Your task is to find a number K which make a[K] = b[1], a[K + 1] = b[2], ...... , a[K + M - 1] = b[M]. If there are more than one K exist, output the smallest one.

Input

The first line of input is a number T which indicate the number of cases. Each case contains three lines. The first line is two numbers N and M (1 <= M <= 10000, 1 <= N <= 1000000). The second line contains N integers which indicate a[1], a[2], ...... , a[N]. The third line contains M integers which indicate b[1], b[2], ...... , b[M]. All integers are in the range of [-1000000, 1000000].

Output

For each test case, you should output one line which only contain K described above. If no such K exists, output -1 instead.

Sample Input

2
13 5
1 2 1 2 3 1 2 3 1 3 2 1 2
1 2 3 1 3
13 5
1 2 1 2 3 1 2 3 1 3 2 1 2
1 2 3 2 1

Sample Output

6
-1

题目大意

给你两个数字序列,你的任务是再序列a中找到和序列b完全匹配的子串,如果有多个匹配的位置,输出最小的那个,如果没有输出-1。

代码

#include <iostream>
#include <cstdio>
using namespace std;
const int MAXM = 10000;
const int MAXN = 1000000;
int nextTable[MAXM];
int pattern[MAXM];
int text[MAXN];
//创建next表
void GetNextTable(int m){
    int j = 0;
    nextTable[j] = -1;
    int i = nextTable[j];
    while (j < m){
        if(i == -1 || pattern[j]==pattern[i]){  //公共前缀后缀增长
            i++;
            j++;
            nextTable[j]=i;
        }else{                                  //公共前缀后缀不匹配
            i = nextTable[i];
        }
    }
}
int KMP(int n, int m){
    GetNextTable(m);
    int i = 0;
    int j = 0;
    while (i < n && j < m){
        if( j == -1 || text[i] == pattern[j]){     //当前字符匹配成功
            i++;
            j++;
        }else{
            j = nextTable[j];                 //当前字符匹配失败
        }
    }
    if(j == m){                 //模式串匹配成功
        return i-j+1;
    }else{                      //模式串匹配失败
        return -1;
    }
}
int main(){
    int caseNumber;
    scanf("%d",&caseNumber);
    while (caseNumber--) {
        int n, m;
        scanf("%d%d",&n,&m);
        for (int i = 0; i < n; ++i) {
            scanf("%d", &text[i]);
        }
        for (int j = 0; j < m; ++j) {
            scanf("%d", &pattern[j]);
        }
        printf("%d\n", KMP(n, m));
    }
    return 0;
}

POJ Oulipo

Description

The French author Georges Perec (1936–1982) once wrote a book, La disparition, without the letter ‘e‘. He was a member of the Oulipo group. A quote from the book:

Tout avait Pair normal, mais tout s’affirmait faux. Tout avait Fair normal, d’abord, puis surgissait l’inhumain, l’affolant. Il aurait voulu savoir où s’articulait l’association qui l’unissait au roman : stir son tapis, assaillant à tout instant son imagination, l’intuition d’un tabou, la vision d’un mal obscur, d’un quoi vacant, d’un non-dit : la vision, l’avision d’un oubli commandant tout, où s’abolissait la raison : tout avait l’air normal mais…

Perec would probably have scored high (or rather, low) in the following contest. People are asked to write a perhaps even meaningful text on some subject with as few occurrences of a given “word” as possible. Our task is to provide the jury with a program that counts these occurrences, in order to obtain a ranking of the competitors. These competitors often write very long texts with nonsense meaning; a sequence of 500,000 consecutive ‘T‘s is not unusual. And they never use spaces.

So we want to quickly find out how often a word, i.e., a given string, occurs in a text. More formally: given the alphabet {‘A‘, ‘B‘, ‘C‘, …, ‘Z‘} and two finite strings over that alphabet, a word W and a text T, count the number of occurrences of W in T. All the consecutive characters of W must exactly match consecutive characters of T. Occurrences may overlap.

Input

The first line of the input file contains a single number: the number of test cases to follow. Each test case has the following format:

  • One line with the word W, a string over {‘A‘, ‘B‘, ‘C‘, …, ‘Z‘}, with 1 ≤ |W| ≤ 10,000 (here |W| denotes the length of the string W).
  • One line with the text T, a string over {‘A‘, ‘B‘, ‘C‘, …, ‘Z‘}, with |W| ≤ |T| ≤ 1,000,000.

Output

For every test case in the input file, the output should contain a single number, on a single line: the number of occurrences of the word W in the text T.

Sample Input

3
BAPC
BAPC
AZA
AZAZAZA
VERDI
AVERDXIVYERDIAN

Sample Output

1
3
0

题目大意

分析

给你一个文本串,再给你一个模式串,文本串中有多少个子串与模式串完全匹配。这道题其实和上道题非常相似,只不过上道题在遇到第一个匹配的地方后,会直接停止向后搜索,并输出位置。本题需要遍历完整文本串,并记录匹配成功的次数。

代码

#include<iostream>
#include<cstdio>
#include<string>

using namespace std;

const int MAXM = 10000;

int nextTable[MAXM];
//创建next表
void GetNextTable(string pattern){
    int m = pattern.size();
    int j =0;
    nextTable[j] = -1;
    int i = nextTable[j];
    while (j < m){
        if(i == -1||pattern[j]==pattern[i]){
            i++;
            j++;
            nextTable[j]=i;
        }else{
            i =nextTable[i];
        }
    }
}
int KMP(string text,string pattern){
    GetNextTable(pattern);
    int n = text.size();
    int m = pattern.size();
    int i = 0;
    int j = 0;
    int number = 0;  //记录匹配次数
    while(i < n){
        if(j==-1||text[i]==pattern[j]){//当前字符匹配成功
            i++;
            j++;
        }else{ //当前字符匹配失败
            j=nextTable[j];
        }
        if(j==m){//模式串匹配成功
            number++;
            j=nextTable[j];
        }
    }
    return number;
}
int main(){
    int caseNumber;
    scanf("%d",&caseNumber);
    while(caseNumber--){
        string pattern, text;
        cin>> pattern >> text;
        printf("%d\n",KMP(text,pattern));
    }
    return 0;
}

KY186 字符串匹配

题目描述

读入数据string[ ],然后读入一个短字符串。要求查找string[ ]中和短字符串的所有匹配,输出行号、匹配字符串。匹配时不区分大小写,并且可以有一个用中括号表示的模式匹配。如“aa[123]bb”,就是说aa1bb、aa2bb、aa3bb都算匹配。

输入描述:

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

输出描述:

输出匹配到的字符串的行号和该字符串(匹配时不区分大小写)。

输入

4
Aab
a2B
ab
ABB
a[a2b]b

输出

1 Aab
2 a2B
4 ABB

代码

#include<iostream>
#include<string>
using namespace std;

void ToLower(string &pattern)
{
    for(int j = 0;j < pattern.size();j++)
    {
        if(pattern[j] >= ‘A‘ && pattern[j] <= ‘Z‘)
        {
            pattern[j] = char(pattern[j] + 32);
        }
    }
}
int main()
{
    int n;
    string pattern;
    while(cin >> n)
    {
        string s[n],p[n];
        for(int i = 0;i < n;i++)
        {
            cin >> s[i];
            p[i] = s[i];
            ToLower(s[i]);
        }
        cin >> pattern;
        ToLower(pattern);
        for(int i = 0;i < n;i++)
        {
            int j = 0,k = 0;
            while(j < s[i].size() && k < pattern.size())
            {
                bool flag = false;
                if(pattern[k] == ‘[‘)
                {
                    k++;
                    while(pattern[k] != ‘]‘)
                    {
                        if(pattern[k] == s[i][j])
                        {
                            flag = true;
                        }
                        k++;
                    }
                    if(!flag){
                        break;
                    }
                    else
                    {
                        k++;
                        j++;
                    }
                }
                else if(s[i][j] == pattern[k])
                {
                    j++;
                    k++;
                }
                else
                {
                    break;
                }
            }
            if(j == s[i].size() && k == pattern.size())
            {
                cout << i + 1 << " " << p[i] << endl;
            }
        }
        
    }
}

KY91 String Matching

题目描述

Finding all occurrences of a pattern in a text is a problem that arises frequently in text-editing programs. Typically,the text is a document being edited,and the pattern searched for is a particular word supplied by the user. We assume that the text is an array T[1..n] of length n and that the pattern is an array P[1..m] of length m<=n.We further assume that the elements of P and T are all alphabets(∑={a,b...,z}).The character arrays P and T are often called strings of characters. We say that pattern P occurs with shift s in the text T if 0<=s<=n and T[s+1..s+m] = P[1..m](that is if T[s+j]=P[j],for 1<=j<=m). If P occurs with shift s in T,then we call s a valid shift;otherwise,we calls a invalid shift. Your task is to calculate the number of vald shifts for the given text T and p attern P.

输入描述:

For each case, there are two strings T and P on a line,separated by a single space.You may assume both the length of T and P will not exceed 10^6.

输出描述:

You should output a number on a separate line,which indicates the number of valid shifts for the given text T and pattern P.

输入

abababab abab

输出

3

题目大意

分析

代码

#include<iostream>
#include<cstdio>
#include<string>

using namespace std;

const int MAXM = 10000;

int nextTable[MAXM];
//创建next表
void GetNextTable(string pattern){
    int m = pattern.size();
    int j =0;
    nextTable[j] = -1;
    int i = nextTable[j];
    while (j < m){
        if(i == -1||pattern[j]==pattern[i]){
            i++;
            j++;
            nextTable[j]=i;
        }else{
            i =nextTable[i];
        }
    }
}
int KMP(string text,string pattern){
    GetNextTable(pattern);
    int n = text.size();
    int m = pattern.size();
    int i = 0;
    int j = 0;
    int number = 0;  //记录匹配次数
    while(i < n){
        if(j==-1||text[i]==pattern[j]){//当前字符匹配成功
            i++;
            j++;
        }else{ //当前字符匹配失败
            j=nextTable[j];
        }
        if(j==m){//模式串匹配成功
            number++;
            j=nextTable[j];
        }
    }
    return number;
}
int main(){
    string pattern, text;
    while(cin>>text>>pattern){
        printf("%d\n",KMP(text,pattern));
    }
    return 0;
}

字符串

标签:信息   部分   sam   bin   字符串长度   core   add   flag   other   

原文地址:https://www.cnblogs.com/zhangzizi/p/14477886.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!