?? matchall.cpp
字號:
#include<iostream>
#include<string>
#include<fstream>
using namespace std;
class NoMem{};
class OutOfBounds{};
class String
{
public:
String(char *s="");
String(const String& s);
~String();
String& operator=(const String& s);
bool operator==(const String& s)const;
int Length()const;
String operator+(const String& s)const;
void operator+=(const String& s);
int Find(char c,int start)const;
String SubStr(int index,int count)const;
void Insert(const String& s,int index);
void Delete(int index, int count);
int ReadString(istream &is=cin,char delimiter='\n');
void PrintString( )const;
int Match(String& t,int &i);
void Prefix();
void ModifiedPrefix();
//private:
char *str;
int size;
int *pre; //前綴函數(shù)數(shù)組
};
String::String(char *s)
{
int n;
n=strlen(s)+1;
//為字符數(shù)組分配空間
str=new char[n];
//若空間分配失敗則拋出異常
if (str==0) throw NoMem();
size=n;
//將字符串拷貝到本對象字符數(shù)組中
strcpy(str,s);
//為前綴函數(shù)數(shù)組分配空間
pre=new int[size];
if (pre==0) throw NoMem();
}
String::String(const String& s)
{
int n;
n=s.size;
//為本對象的字符數(shù)組分配空間
str=new char[n];
if (str==0) throw NoMem();
size=n;
//將對象s的字符數(shù)組拷貝到本對象的字符數(shù)組中
strcpy(str,s.str);
//為前綴函數(shù)數(shù)組分配空間
pre=new int[size];
if (pre==0) throw NoMem();
}
String::~String()
{
//釋放本對象字符數(shù)組所占用空間
delete []str;
delete []pre;
}
String& String::operator=(const String& s)
{
//若本對象字符數(shù)組空間不等于s的字符數(shù)組空間
if (size!=s.size)
{
//刪除本對象字符數(shù)組空間
delete []str;
//為本對象分配一塊與s的字符數(shù)組同等大小的空間
str=new char[s.size];
if (str==0) throw NoMem();
size=s.size;
}
//將s的字符數(shù)組拷貝到本對象的字符數(shù)組中
strcpy(str,s.str);
//返回賦值后的本類對象
return *this;
}
bool String::operator==(const String& s)const
{
return strcmp(str,s.str)==0;
}
int String::Length( )const
{
return size-1;
}
String String::operator+(const String& s) const
{
//創(chuàng)建新串對象temp
String temp;
//釋放temp的空串所占用空間
delete []temp.str;
//為temp的字符數(shù)組分配空間,以存放連接后的串
int n=size+s.size-1;
temp.str=new char[n];
if (temp.str==0) throw NoMem( );
temp.size=n;
//將本對象存放的串拷貝到temp中
strcpy(temp.str,str);
//將s中的串連接至temp的串后
strcat(temp.str,s.str);
//返回串對象temp
return temp;
}
void String::operator+=(const String& s)
{ char *temp;
//為存放連接后的串的字符數(shù)組temp分配空間
temp=new char[size+s.size-1];
if (temp==0) throw NoMem();
//將本對象存放的串拷貝到temp中
strcpy(temp,str);
//將s中存放的串連接至temp中串的后部
strcat(temp,s.str);
//釋放本對象的數(shù)組空間,令temp成為其數(shù)組空間
delete []str;
str=temp;
size=size+s.size-1;
}
int String::Find(char c,int start) const
{
//若start向下越界,則令start=0
if (start<0) start=0;
//若start向上越界,則查找失敗,返回-1
if (start>size-1) return -1;
/*使用strchr函數(shù)在當前串的位置start起查找字符
c的首次出現(xiàn)位置,令p指向找到的字符*/
char *p=strchr(&str[start],c);
//若查找失敗,返回-1
// if (p==0) return -1;
//若查找成功,返回該字符所在下標
// return p-str;
int ret;
if(p!=0)
ret=int(p-str);
else ret=-1;
return ret;
}
String String::SubStr(int index,int count)const
{ //若下標<0,則令其為0
if (index<0) { count+=index; index=0; }
//若子串的字符個數(shù)count<0,則拋出越界異常
if (count<0) throw OutOfBounds();
/*若下標超出或等于串長,或者子串字符個數(shù)
為0, 則返回空串對象*/
String s;
if (index>=size-1 || count==0) return s;
/* 若子串字符個數(shù)多于串中從index開始至串尾的 字符個數(shù),令count為串中從index開始的字符個數(shù)*/
if (count>size-index-1) count=size-index-1;
//釋放串對象s的字符數(shù)組空間
delete []s.str;
//為串對象s的字符數(shù)組分配空間
s.str=new char[count+1];
if (s.str==0) throw NoMem();
s.size=count+1;
//將子串拷貝到s中并設置串結束標記’\0’
char *p,*q; int i;
for ( i=0,p=s.str,q=&str[index]; i<count; i++)
*p++=*q++;
*p=0;
//返回存放子串的串對象s
return s;
}
void String::Insert(const String &s,int index)
{
//若插入位置向下越界,則令其為0
if (index<0) index=0;
//若插入位置向上越界,則令其為串尾位置
if (index>size-1) index=size-1;
//為字符數(shù)組temp分配空間,以存放插入后的串
char *temp;
temp=new char[size+s.size-1];
if (temp==0) throw NoMem();
//將當前串的前index個字符拷貝到temp中
char *p,*q; int i;
for (i=0,p=temp,q=str; i<index; i++)
*p++=*q++;
//將s中存放的串放至temp中
strcpy(p,s.str);
p+=s.size-1;
/*若當前串除前index個字符外還有字符,將
剩余字符放至temp中*/
strcpy(p,&str[index]);
delete []str;
str=temp;
size=size+s.size-1;
}
void String::Delete(int index,int count)
{ //若被刪字符數(shù)count<0,則拋出異常
if (count<0) throw OutOfBounds();
/*若被刪位置向上越界或被刪字符數(shù)為0,則
不做任何刪除操作*/
if (index>=size-1 || count==0) return;
/*若被刪位置向下越界,則令被刪字符數(shù)減少
并令被刪位置為0*/
if (index<0) { count+=index; index=0; }
/*若被刪字符數(shù)count多于串中從位置index開始的所有字符,則令count為串中從index開始的字符數(shù)目*/
if (count>size-index-1) count=size-index-1;
//為字符數(shù)組分配空間以存放刪除后的串
char *temp;
temp=new char[size-count];
if (temp==0) throw NoMem();
/*將當前串的前index個字符拷貝到temp中
并設置串結束符*/
strncpy(temp,str,index);
temp[index]='\0';
/*若當前串從位置index起刪除count個字符
后還有剩余字符,則將其拷貝到temp中*/
if (index<size-count-1)
strcat(temp,&str[index+count]);
/*釋放當前串對象的字符數(shù)組所占用空間,并令temp成為其數(shù)組空間*/
delete []str;
str=temp;
size=size-count;
}
int String::ReadString(istream & istr,char delimiter)
{
char temp[256];
//從輸入流中接收一系列字符至temp,以delimiter為終止符
if (istr.getline(temp,256,delimiter))
{ //釋放本對象的字符數(shù)組空間
delete []str;
int n=strlen(temp)+1;
//為本對象申請新的字符數(shù)組空間存放輸入的字符
str=new char[n];
if (str==0) throw NoMem();
size=n;
//將temp中字符串拷貝到當前串中
strcpy(str,temp);
//返回接收到的字符數(shù)
return size-1;
}
//若字符接收失敗,則返回-1
else return -1;
}
void String::PrintString()const
{cout<<str<<endl;}
void String::Prefix()
{
int m=Length();
delete[]pre;
pre=new int[m+1];
if (pre==0)throw NoMem();
pre[0]=0;
int k=0;
for (int i=1;i< m;i++)
{
while((*(str+i-1)!=*(str+k))&&(k>0))
k=pre[k];
if (*(str+i-1)=*(str+k))
pre[i]=++k;
else pre[i]=0;
}
}
void String::ModifiedPrefix()
{
int *f;
int m=Length();
f=new int[m+1];
Prefix();
for (int i=1;i<=m;i++)
f[i]=pre[i];
for(i=1;i<m;i++)
{
int k=f[i];
if((k==0) ||(*(str+i)!=*(str+k)))
pre[i]=k;
else pre[i]=pre[k];
}
delete []f;
}
int String::Match(String&t,int &i)
{
int j=0;
int n=Length(),m=t.Length();
t.ModifiedPrefix();
while( (i<=n)&& (j<m) )
{
if (str[i-1]==t.str[j])
{
i++;
j++;
}
else
if(j==0)i++;
else j=t.pre[j-1];
}
if(j<m)
return 0;
else
return i-m;
}
void Mov(int Temp,int n,int flag[])
{
for(int i= 1;i<= n;i++)
if(flag[i]== 0)
{
flag[i]= Temp;
return;
}
}
int main()
{
int n,m,i;
string str1,str2;
ifstream in("input.txt");
getline(in,str1);
getline(in,str2);
n=str1.length()+1;
m=str2.length()+1;
int *flag= new int[n];
for(i= 1;i<= n-1;i++) flag[i]=0;
String Str1,Str2;
Str1.str=new char[n];
Str1.size=n;
for(i= 0;i<n-1;i++) Str1.str[i]=str1.at(i);
Str2.str=new char[m];
Str2.size=m;
for(i= 0;i<m-1;i++) Str2.str[i]=str2.at(i);
i= 1;
while(i<= n-1)
{
int Temp= Str1.Match(Str2,i);
if(Temp!= 0)
{
Mov(Temp,n-1,flag);
i= Temp+1;
}
}
ofstream out("output.txt");
if (flag[1]==0)
out<<"0";
else
for(i= 1;i<= n-1;i++)
if(flag[i]!= 0)
out<<flag[i]<<" ";
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -