BJFU-Algorithm Design and Analysis-Experiment 7_string

字符串操作

描述

给定一个字符串S,打印操作结果。操作如下:

Insert x i:将字符x插入位置i;

Erase x:删除字符串S中的所有字符x;

Replace x y:将字符串S中的所有字符x替换为y;

Size:打印字符串的大小;

Reverse:打印字符串S的反转;在此操作中不要更改S;

Sub i j:打印从位置i到j的S的子串;

Find str:打印字符串S中第一个str的起始位置;如果str不是S的子字符串,则打印-1。

输入

每个测试用例的第一行包含一个字符串S。接下来是5行。第一行包括字符x和整数i,表示“Insert x
i”;第二行是字符x,意思是“擦除x”;第三行是两个字符x和y,意思是“替换xy”;

第四行是两个整数i和j,意思是“Sub i j”;最后一行是字符串str,意思是“Find
str”。所有的输入字符都是英文大写或小写字母。字符串的长度将不超过100。输入将在文件末尾终止。

输出

对于每个测试用例,必须在第一行打印“casei:”。然后,对于每个操作,将其结果打印在一行中。每个测试用例后面都有一个空行。

输入样例 1
string
a 1
g
n g
3 4
str
String
a 0
n
g n
2 5
tr
输出样例
Case 1:
Insert->satring
Erase->satrin
Replace->satrig
Size->6
Reverse->girtas
Sub->ri
Find->-1

Case 2:
Insert->aString
Erase->aStrig
Replace->aStrin
Size->6
Reverse->nirtSa
Sub->trin
Find->2

easy,考察了一些函数:参考这位博主
代码如下:

#include <iostream>
#include <string>
#include<string.h>
#include<stdio.h>
#include <algorithm>
using namespace std;
string s,op;
char t,g;
int location,lo;
int cnt=0;
int main()
{
	
	while(cin>>s)
	{
		cout<<"Case "<<++cnt<<":"<<endl;
		//插入 
		cin>>op>>location;
		cout<<"Insert->"<<s.insert(location,op)<<endl;
		//删除 
		cin>>t;
		s.erase(remove(s.begin(),s.end(),t),s.end());
		cout<<"Erase->"<<s<<endl;
		//替代 
		cin>>t>>g;
		replace(s.begin(),s.end(),t,g);
		cout<<"Replace->"<<s<<endl; 
		//长度 
		cout<<"Size->"<<s.size()<<endl;
		//反转 
		string s1=s;
		reverse(s1.begin(),s1.end());
		cout<<"Reverse->"<<s1<<endl;
		//子串 
		cin>>location>>lo;
		s1=s.substr(location,lo-location+1);
		cout<<"Sub->"<<s1<<endl;
		//是否子串
		cin>>s1;
		int pos;
		pos=s.find(s1,0);
		cout<<"Find->"<<pos<<endl;
		cout<<endl;
	}
	return 0;
 } 

**

Sequence Matching(字符串匹配)

**

描述

Given two strings A and B. Your task is to find the position K which
make A[K]=B[0], A[K+1]=B[1], … A[K+M] = B[M]. If there exist
multiple answers, output the smallest one. All the inputs will be
lowercase letters.

输入

The first line of the input is an integer T which indicates the number
of the test cases. Each test case contains two lines. The first line
is string A (A.length < 10^6). The second line is string B (B.length <
10^4).

输出

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

==输入样例 1 ==

2
string
str
string
int
输出样例 1

0
-1
kmp,但是不知道为什么过不了,所以用了find();
ac代码:

#include <iostream>
#include <string>
#include <string.h>
using namespace std;
string a,b;
int k;
int T;
int main()
{
	cin>>T;
	while(T--)
	{
		cin>>a>>b;
		int pos=a.find(b,0);
		cout<<pos<<endl;
	}
	return 0;
}

kmp:

#include <iostream>
#include <string>
#include <string.h>
using namespace std;
string a,b;
int k;
int T;
void getNext(int next[],int length)
{
	int j=0,k=-1;
	next[0]=-1;
	while(j<length)
	{
		if(k==-1||b[j]==b[k])
		{
			j++;k++;
			next[j]=next[k];
		}
		else
		k=next[k];
	}
}
int KMP(int k,int next[])
{
	int posa=0,posb=k;
	int lengthb=b.size();
	int lengtha=a.size();
	while(posa<lengtha&&posb<lengthb)
	{
		if(posb==-1||b[posb]==a[posa])
		{
			posb++;posa++;
		}
		else
		posb=next[posb];
	}
	if(posb<lengthb)
		return -1;
	else
		return posa-lengthb;
}
int main()
{
	cin>>T;
	while(T--)
	{
		cin>>a>>b;
		const int length=b.size();
		int next[length];
		memset(next,0,sizeof(next));
		getNext(next,length);
		int pos=KMP(0,next);
		cout<<pos<<endl;
	}
	return 0;
}

**

The Curse Dictionary

**

描述

Akko is learning magic in Luna Nova Magical Academy. It is said that
there are 10^5 types of different curses in the magic world. It is too
hard for Akko to memorize them all. Fortunately, Proffesor Meridies
says that she can help Akko make a Curse Dictionary. When Akko hears a
curse, the Dictionary will tell her the effect of the curse. Also,
when Akko wants to do something, the Dictionary will find the curse
for her. If there is no such curse, the Dictionary will be silence.
Can you write a program to reproduce the Curse Dictionary?

输入

Each test case will contain no more than 10^5 curses. Each curse will
be like “[name] effect”. The name and effect of the curse will only
contain lowercase letters. There will be only one space between ‘]’
and the string after it. The length of the name will not exceed 20 and
the length of the effect will not exceed 80. The end of the dictionary
is a line of “END”. After all curses there will be an integer N
(1<=N<1000), followed by N queries. Every query will be a “[curse
name]” or a “curse effect”. There will be only one test case in each
input file.

输出

For each test case, you must output the effect of the curse by its
name or the name of the curse by its effect. If there is no curse
satisfying the condition, print “silence”.

输入样例 1

[tiafraere] flying with broom
[nodylledelfrydol] shiny rod turns in to a bow
[pwysigIwpentyrru] shiny rod turns into a great axe
[lecheilebeidhmuid] heal the mind
[angenamyneddag] shiny rod turns into a sprinkler
[atraddodiadagrym] shiny rod turns into a broom with incredible speed
[diolch] heal the wound
[fasannsileshalira] change the world
END
4
[lecheilebeidhmuid] f
lying with broom
[expectopatronum]
light the wand
输出样例 1

heal the mind
tiafraere
silence
silence

用哈希字符,hdu1880的题,代码是copy这位博主的

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int c=10000;
struct myhash{
    struct node {
        long long key;//若key%c相同辅助判重
        string s1;//若key相同辅助判重
        string s2;//要查找的东西,字符串s1对应的字符串s2
        node* next;//链表用指针
    }a[c+5];
    void push(long long x,string s1,string s2) {//插入函数
        if(a[x%c].key==0) {//如果数组x%c处没有元素,直接插入
            a[x%c].key=x;
            a[x%c].s1=s1;
            a[x%c].s2=s2;
        } else {//如果有,链表插入新节点(头插入)
            node *tmp=new node();
            tmp->key=x;
            tmp->s1=s1;
            tmp->s2=s2;
            tmp->next=a[x%c].next;//此处相当于head
            a[x%c].next=tmp;
        }
    }
    string found(long long x,string s1) {//查找函数
        if(a[x%c].key==x&&a[x%c].s1==s1) return a[x%c].s2;//如果字符串在数组里,直接返回对应的字符串s2
        if(a[x%c].key==0) return "silence";//如果数组里没有元素,链表里肯定也没有,返回what?
        else {
            node* tmp=a[x%c].next;//遍历链表查找
            while(tmp!=NULL) {
                if(tmp->key==x&&tmp->s1==s1) return tmp->s2;
                tmp=tmp->next;
            }
            return "silence";
        }
    }
};
myhash H1,H2;//H1存储名字对应的内容,H2存储内容对应的名字
long long to_num(string str){//前8位的乘积hash 
    long long ans=1;
    int len=str.length();
    if(len>8) len=8;
    for(int i=0;i<len;i++) ans*=str[i];
    return ans;
}
int main() {
    int t; 
    string str,s1,s2;
    while(1) {
        int i;
        getline(cin,str);//有空格,必须用getline
        if(str=="END") break;
        for(i=0; i<str.length(); i++) {
            if(str[i]==']') break;//找到咒语名字和内容的分界点
        }
        s1=str.substr(0,i+1);
        s2=str.substr(i+2,str.length()-i-1);
        //将str分为两部分,s1是名字,s2是内容
        H1.push(to_num(s1),s1,s2);
        H2.push(to_num(s2),s2,s1);
    }
    cin>>t;
    getchar();//输入一个换行符,否则换行符会被getline读入到str中,导致在哈希表中查找'\n',多输出一个"what?"
    while(t--){
        getline(cin,str);
        bool have_kuo=false;//区分输入的是内容还是名字
        for(int i=0;i<str.length();i++){
            if(str[i]==']'){
                have_kuo=true;
                break;
            }
        } 
        string tmp;
        if(have_kuo) tmp=H1.found(to_num(str),str);
        else tmp=H2.found(to_num(str),str);
        if(tmp[0]=='['){
            for(int i=1;i<tmp.length()-1;i++)  cout<<tmp[i];//输出咒语名字时不带括号
            cout<<endl;
        }
        else cout<<tmp<<endl;
    }
}

hashing strings

gets() was deprecated in C++14, use getline instead

for char arr[], use cin.getline(arr,sizeof(arr));

for string arr, use getline(cin, arr);


Prefixed?(字典树)


描述

Given some words, can you figure out if there are words prefixed with
a string? You should notice that the word itself is a prefix of it.
All the letters will be lowercase.

输入

The first part of the input is a word list. The length of each word
will not exceed 10. Then a blank line follows which means the end of
the word list. The second part are queries, and each query is a
string. The sum of their lengths will not exceed 10^6. There will be
only one test case in each input file.

输出

For each test case, if there’s a word (or words) prefixed with the
string, print “YES”, otherwise print “NO”.

输入样例 1

abandon
abnormal
base
background

ba
bb
band
ab
输出样例 1

YES
NO
NO
YES

字典树

#include <bits/stdc++.h>
using namespace std;
struct Trie{    // Trie
    Trie* next[26];
    int num;    //the number of words prefixed with the current string
    Trie() {   // construction
       for(int i=0;i<26;i++) next[i] = NULL;
       num=0;
    }
};
Trie root;
void Insert(char str[]){    // insert str to the trie
    Trie *p = &root;
    for(int i=0;str[i];i++){    // process every character
        if(p->next[str[i]-'a']==NULL)    // if the character has no corresponding trie node
            p->next[str[i]-'a'] = new Trie;    // create the trie node
        p = p->next[str[i]-'a'];
        p->num++;
    }
}
int Find(char str[]){    //return the number of words prefixed with str
    Trie *p = &root;
    for(int i=0;str[i];i++){    // find the str in the trie
        if(p->next[str[i]-'a']==NULL) // find none
            return 0;
        p = p->next[str[i]-'a'];
    }
    return p->num;
}
int main(){
    char str[11];
    while(cin.getline(str,sizeof(str)))
	{
        if ( !strlen(str) )  break;  // input an empty line 
        Insert(str);
    }
    while(cin.getline(str,sizeof(str))) 
	{
		if(Find(str)==0)
			cout<<"NO"<<endl;
		else
			cout<<"YES"<<endl;
	}
    return 0;
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值