串的基础

引言:字符串是由字符组成的有限序列,从逻辑结构看,串是一种“特殊的线性表”,其特殊性在于线性表中的每个元素是一个字符。作为
一种抽象数据类型,串有自己的一组操作,其操作特点与线性表不同。

1.串的基本概念
a.串定义:串(string)是由零个或多个字符组成的有限序列,又叫字符串。一般记为 s=”a1a2...an”( n≥0 )。串中的字符数目n成为串的长度,有限。零个字符的串成为空串。一个字符在串中的位置值该字符在串中的“序号”,约定串中第一个字符的序号为0,-1表示该字符不在指定串中。
注意:空串和空格串是不一样的,空串一个元素都没有,空格串只有空格元素。

b.子串:由串s中任意连续字符组成的一个子序列叫做s的子串。比如“ta”是“data”的子串。
(注意:1.空串是任意串的子串 2.任意串s都是它自身的子串 3.除自身外,其余的子串都是其s的真子串 4.子串的序号指该子串的第一个字符在主串中的序号)

c.串比较
两个串的比较依次由对应位置的字符进行比较,如果在对应位置上,有不同,则两个串的大小由对应位置的第一个不同字符的大小决定,如果串长度不一样而对应位置的字符相同时,较长的串较大,如果对应的字符和长度都相同,则两个串相等。

2.串抽象数据类型
a.串的基本操作有:创建一个串,求串长度,读取或设置字符,求子串,插入,删除,连接,判断相等,查找,替换等。
(注意:求子串,插入,查找等操作以子串为单位,一次操作处理多个字符)

b.串抽象数据类型的SString接口声明:
public interface SString
{
int length(); //返回串的长度
char charAt(int i) //返回第i(i大于等于0)个字符
SString concat(SString str);//返回当前串与str串连接生成的新串
SString substring(int begin,int end); //返回串中字符序号从begin至end-1的子串
void setCharAt(int i,char ch); //设置第i个字符为ch
SString insert(int i,SString str);//在第i个字符处插入str串
SString delete(int begin,int end);//删除从begin到end-1的子串
int indexOf(SString pattern); //返回模式串pattern在串中的首次匹配位置
}

3.串的实现

1)说明:其有顺序存储和链式存储两种存储结构。其方式有以下两种:

a..串的顺序存储结构:串的顺序存储结构采用”字符数组”将串中的字符序列依次连续存储在数组的相邻单位中。
其使用字符数组有两种方案:
a.数组容量等于串长度。这种方式串不易增加字符,通常用于存储串常量。
b.数组容量大于串长度。这种方式串便于增加字符,通常用于存储串变量,此时还有要一个整型变量记载串的长度。
(优点:串具有随机存储功能,存取指定未知字符的时间复杂度为O(1);
缺点:1.删除或者插入元素时需要移动元素,平均移动数据量是串长度的一半
2.当数组容量不够时,需要重新申请一个更大的数组,并复制原数组中的所有元素。

b..串的链式存储结构
.种类
1.单字符链表:每个结点的数据域只包含一个字符的单链表(缺:占用存储空间太多)
2.块链表:每个结点的数据域包含若干字符的单链表。(缺:插入和删除操作需要移动元素,效率较低)

2)串的具体实现(串一般是顺序表实现的,所以链表的实现这边就不说了)

接口准备:

package org.Stone6762.MString;

/**
* @MString
* @Stone6762
* @Description
*/
public interface MString {

/**
* @Title: clear
* @Description: TODO(将字符串清空)
*/
public void clear();

/**
* @Title: isEmpty
* @Description: TODO(判断是否为空)
* @return
*/
public boolean isEmpty();

/**
* @Title: length
* @Description: TODO(求字符串的长度)
* @return
*/
public int length();

/**
* @Title: charAt
* @Description: TODO(取出字符串中的某一个下标下的字符)
* @param index
* @return
*/
public char charAt(int index);

/**
* @Title: subString
* @Description: TODO(根据起始和结束的下标来截取某一个子串)
* @param begin要截取部分的起始部分,包括起始部分
* @param end截止到end,不包括end
* @return
*/
public MString subString(int begin, int end);

/**
* @Title: insert
* @Description: TODO(根据下标将一个字符串插入到指定的位置)
* @param offset要插入的字符串的第一个位置
* @param str
* @return
*/
public MString insert(int offset, MString str);

/**
* @Title: delete
* @Description: TODO(删除掉串中的某一部分)
* @param begin
* @param end
* @return
*/
public MString delete(int begin, int end);

/**
* @Title: concat
* @Description: TODO(将一个字符串连接到该字符串的末尾)
* @param str
* @return
*/
public MString concat(MString str);

/**
* @Title: compareTo
* @Description: TODO(两个字符串进行比较)
* @param str
* @return
*/
public int compareTo(MString str);

/**
* @Title: indexOf
* @Description: TODO(在本字符串中,从begin位置开始,检索某一个字符串第一次出现的位置)
* @param str
* @param begin
* @return
*/
public int indexOf(MString str, int begin);
}

串的顺序存储实现

package org.Stone6762.MString.imple;

import org.Stone6762.MString.MString;

/**
* @SeqString
* @Stone6762
* @Description
*/
public class SeqString implements MString {

/**
* @Fields strvalue : TODO(储存串中的每一个元素)
*/
private char[] strvalue;

/**
* @Fields curlen : TODO(记录当前的串的长度)
*/
private int curlen;

/**
*  @Description: TODO(构造方法一,默认的)
*
*/
public SeqString() {
this.strvalue = new char[0];
this.curlen = 0;
}

/**
*  @Description: TODO(构造方法二,设置顺序存储的串的最大长度)
*
* @param maxSize
*/
public SeqString(int maxSize) {
this.strvalue = new char[maxSize];
this.curlen = 0;
}

/**
*  @Description: TODO(构造方法三、以一个字符串构造串对象)
*
* @param str
*/
public SeqString(String str) {
strvalue = str.toCharArray();
curlen = strvalue.length;
}

/**
*  @Description: TODO(构造方法四,以一个字符数组构造串对象)
*
* @param value
*/
public SeqString(char[] value) {
this.strvalue = new char[value.length];
for (int i = 0; i < value.length; i++) {
strvalue[i] = value[i];
}
curlen = value.length;

}

public char[] getStrvalue() {
return strvalue;
}

public int getCurlen() {
return curlen;
}

@Override
public void clear() {
this.curlen = 0;
}

@Override
public boolean isEmpty() {
return this.curlen == 0;
}

@Override
public int length() {
return this.curlen;
}

@Override
public char charAt(int index) {
if (index < 0 || index >= this.curlen) {
throw new StringIndexOutOfBoundsException();
}
return strvalue[index];
}

/**
* @Description: TODO( 扩充串存储空间容量,参数指定容量 )
* @param newCapacity
*/
public void allocate(int newCapacity) {
/*
* 先将原来的数据进行保存,然后根据参数创建一个目标大小的存储空间 最后将保存的数据存储到新的空间中
*/
char[] tempCArry = this.strvalue;
strvalue = new char[newCapacity];
for (int i = 0; i < tempCArry.length; i++) {
strvalue[i] = tempCArry[i];
}
}

@Override
public MString subString(int begin, int end) {
/*
* 首先要判断想要截取的下标的合法性(不能越界,开始不能大于结束) 然后直接根据下标找到目标字符数组,然后根据字符数组创建一个顺序存储的串
*/
if (begin < 0) {
throw new StringIndexOutOfBoundsException("起始位置不能小于0");
}
if (end > curlen) {
throw new StringIndexOutOfBoundsException("结束位置不能大于串本身的长度" + curlen);
}
if (begin > end) {
throw new StringIndexOutOfBoundsException("起始位置不能大于中止位置");
}
if (begin == 0 && end == curlen) {
return this;
} else {
char[] buffer = new char[end - begin];
for (int i = 0; i < buffer.length; i++) {
buffer[i] = this.strvalue[i + begin];
}
return new SeqString(buffer);
}
}

@Override
public MString insert(int offset, MString str) {
/*
* 首先判断插入位置的合法性(小于0或大于原本串的长度) 然后判断是否能够存储,不能就扩充
* 最后,先将要插入部分的字符向后移,再将要插入的字符插入即可
*/
if (offset < 0 || offset > curlen) {
throw new StringIndexOutOfBoundsException("");
}
int strlen = str.length();
int newlength = strlen + curlen;
if (newlength > this.strvalue.length) {
allocate(newlength);
}
// 将offset后的元素都后移strlen位
for (int i = curlen - 1; i >= offset; i--) {
strvalue[strlen + i] = strvalue[i];
}
// 插入
for (int i = 0; i < strlen; i++) {
strvalue[offset + i] = str.charAt(i);
}
this.curlen = newlength;
return this;
}

@Override
public MString delete(int begin, int end) {

/*
* 首先将判断下标的合法性,起始不能小于0,结束不能超出当前串的长度,起始不能大于结束
* 然后将end以后(包括end)的字符都向前移动到起始的位置。
*/
if (begin < 0) {
throw new StringIndexOutOfBoundsException("起始位置不能小于0");
}
if (end > curlen) {
throw new StringIndexOutOfBoundsException("结束位置不能大于串本身的长度" + curlen);
}
if (begin > end) {
throw new StringIndexOutOfBoundsException("起始位置不能大于中止位置");
}
for (int i = end; i < curlen; i++) {
this.strvalue[begin + i] = this.strvalue[i];
}
curlen = curlen - (end - begin);
return this;
}

@Override
public MString concat(MString str) {
/*
* 首先判断是否能够存储
*/
int newlen = str.length() + curlen;
if (newlen > strvalue.length) {
allocate(newlen);
}
for (int i = 0; i < str.length(); i++) {
strvalue[curlen + i] = str.charAt(i);
}
return this;
}

@Override
public int compareTo(MString str) {
/*
* 首先以一个长度小的为基准,遍历比较,一旦出现不相等,返回比较值。 如果长度相同的部分都相等,返回长度比较值
*/
int len1 = curlen;
int len2 = str.length();
int n = Math.min(len1, len2);

char[] cArry1 = strvalue;
char[] cArry2 = ((SeqString) str).strvalue;
int i = 0;
char c1, c2;
while (i < n) {
c1 = cArry1[i];
c2 = cArry2[i];
if (c1 != c2) {
return c1 - c2;
}
i++;
}
return len1 - len2;
}

@Override
public int indexOf(MString str, int begin) {

return 0;
}
}

特别提醒:这边的indexof()方法未实现,因为较难,所以放在下节讲,这边特别得注意。

补充与扩展:

       Java语言的字符串主要有字符串常量类String,字符串变量类StringBuffer等。这两种串类都采用
顺序存储结构,能够存储任意长度的字符串,实现串的基本操作,并且能够识别序号越界等错误,对数组
占用的存储空间进行控制,具有健壮,安全性好等特点,现在我们就对这两个对象进行分析。

常量字符串类String
模拟java.lang.String类的MyString类的部分声明
(注意:MyString类是最终类,其不能被继承,实现“可比较接口”和“序列化接口”。)

public final class MyString implements Comparable<MyString>,java,io,Serializable
{
private final char[] value; //字符数组,私有最终变量,只能赋值一次。
//构造一个空串
public MyString(){ this.value=new char[0];}

//由字符串常量构造串对象,用其中的函数获得字符串中的字符数组
public MyString(java.lang.String original){ this.value=original.toCharArray();}

//以value数组中从begin开始的count个字符构造串对象
public MyString(char[] value,int begin,int count)
{
this.value=new char[count]; //当value==null时,java抛出空对象异常
for(int i=begin;i<begin+count;i++) //复制数组
this.value[i]=value[i];
}
//以value数组中字符构造串对象
public MyString(char[] value){ this(value,0,value.length); }
//拷贝构造方法,复制对象
public MyString(MyString str){ this(str.value); }
//返回字符串的长度
public int length(){ return this.value.length;}
  
 public char charAt(int i)      //返回第i个字符
    {
           if(i<0||i>this.value.length)
                  throw new StringIndexOutOfBoundsException(i);    //抛出字符串索引越界异常
               return this.value[i];
     }
 
 public java.lang.String toString(){ return new String(this.value);}

实现分析:
a.构造字符串
MyString s1=new MyString(); //构造一个空串
MyString s2=new MyString(“ads”); //以java.lang.String字符串常量构造串对象
char[] letters={‘a‘,‘b‘,‘c‘,‘d‘}; //字符数组,只能在声明时赋值,不能赋值为“abcd"
MyString s3=new MyString(letters); //以字符数组构造串对象
MyString s4=new MyString(s3); //拷贝构造方法

注意:String类和普通类有两点不同,String能够赋值为字符串变量,并且能够使用“+”运算符连接其他类型变量值。但是Mystring类没有实现这两个功能。
String a=“abc";
str=str+"a";

b.常量串中字符的只读属性
String类的字符数组声明为最终变量,所以串中各字符是只读的,String类提供charAt(int i)方法返回第i个字符,不提供setCharAt(int i,char ch)修改第i个字符

c.数组复制
串连接和求子串操作都需要复制字符数组。
方法:
1.for语句
2.java.lang.System.arraycopy(value,0,this.value,0,value.length); //复制数组,功能同上述for语句
3.this.value=java.util.Arrays.copyOf(value,value.length); //复制数组,包括申请数组空间

d.若charAt(int i)方法参数i指定序号错误,抛出字符串序号越界异常

以下为操作String对象的内部方法。
1.获得整数和实数字符串表示的数值。

public static int parseInt(String s) //返回整数字符串s表示的整数值
{
int x=0,i=0;
int sign=s.charAt(0)==‘-‘?-1:1; //符号位,记住正负数标记
if(s.charAt(0)==‘+‘||s.charAt(0)==‘-‘) //跳过符位号
i++;

while(i<s.length()){
if(s.charAt(i)>=‘0‘&&s.charAt(i)<=‘9‘)
{ x=x*10+s.charAt(i++)-‘0‘; } //x记住当前获得的整数值,这就是语法

else throw new NumberFormatException(s); //抛出数值格式异常
}
return x*sign; //返回整数值
}

public static double parseDouble(String s) //返回实数字符串表示的浮点数值
{
int n=s.length(), i=0;
int sign=s.charAt(0)==‘-‘?-1:1;
double x=0,power=10.0E0; //power表示底数为10的幂
if(s.charAt(0)==‘+‘||s.charAt(0)==‘-‘) //跳过符位号
i++;

while(i<n&&s.charAt(i)>=‘0‘&&s.charAt(i)<=‘9‘){ //获得整数部分值
x=x*10+s.charAt(i++)-‘0‘; }
if(i<n&&s.charAt(i)==‘.‘) //若是小数点
{
i++;
while(i<n&&s.charAt(i)>=‘0‘&&s.charAt(i)<=‘9‘) //获得小数部分值
{
x+=(s.charAt(i)-‘0‘)/power;
i++;
power*=10;
}
}
x*=sign;

if(i<n&&(s.charAt(i)==‘E‘||s.charAt(i)==‘e‘)) //处理阶码
{
i++;
power=(s.charAt(i)==‘-‘)?0.1:10; //阶码的符号位决定指数的正负及其运算
if(s.charAt(i)==‘+‘||s.charAt(i)==‘-‘)
{ i++;}

int exp=0;
while(i<n&&s.charAt(i)>=‘0‘&&s.charAt(i)<=‘9‘){
exp=exp*10+s.charAt(i++)-‘0‘; } //获得指数的绝对值

for(int j=0;j<exp;j++)
x*=power;
}
return x;
}

思路:
1.获得正负号,并且跳过
2.获取整数(如果只有整数直接乘上正或者负号)
3.如果有小数点获取小数,加上整数
4.如果有阶码E,e,记住并且获得其指数的绝对值,最后第三步得出的数乘以E^指数或者e^指数。

2.连接串

public MyString concat(MyString str) //返回当前串与制定串str连接生成的新串

if(str==null||str.length()==) //欲连接的串为空时,返回当前串
return this;

char[] buffer=new char[this.value.length+str.length()];
int i;
for(i=0;i<this.value.length;i++) //复制当前串
buffer[i]=this.value[i];

for(int j=0;j<str.value.length;j++) //复制制定串str
buffer[i+j]=str.value[j];

return new MyString(buffer); //以字符数组构造串对象

思路:
1.如果加入的串是空的,就返回当前串
2.如果不为空,创建一个新的数组,其容量为两个数组的总和。
3.利用for循环,将各个数组复制到新的数组里面去。
注意,要被每个数组开始的数不一样。
4.返回以字符数组构造串对象

3.求子串
public MyString substring(int begin,int end) //返回串中序号从begin至end-1的子串

if(begin<0) { begin=0;}
if(end>this.value.length) { end=this.value.length;} //序号容错处理

if(begin>end) throw new StringIndexOutOfBoundsException(end-begin);

if(begin==0&&end=this.value.length) return this;

char[] buffer=new char[end-begin];
for(int i=0;i<end-length;;i++){
buffer[i]=this.value[i+begin];
}
return new MyString(buffer) ; //以字符数组构造串对象

思路:
1.对begin<0,end>this.value.length的序号容错处理。
2.begin>end,抛出异常
3.begin=0,end=this.value.length.返回本串
4.建立新的数组,容量为end-begin,利用for循环复制子串。
5.返回以字符数组构造串对象。

4.比较串相等
public boolean equals(Object obj) //比较当前串是否与obj引用的串相等
{
if(this==obj)
return true;

if(obj instanceof MyString)
{
MyString str=(MyString)obj;
if(this.value.length==str.value.length)
{
for(int i=0;i<this.value.length;i++){
if(this.value[i]!=str.value[i]) {return false;}
}
return true;
}
}
return false;

思路:
1.如果两者对象相等,返回true
2.如果obj是属于MyString的同种类型,强转obj,分两中情况,
如果长度相等,继续处理,长度不等,返回false。
3.继续处理为利用for循环进行遍历确保是否有元素不等,如果是,返回false,如果不是,返回true。

5.比较串的大小
public final class MyString implements Comparable<MyString>,java,io,Serializable
{
public int compareTo(MyString str)         //比较当前串与str串的大小,返回两者差值
   {
       for(int i=0;i<this.value.length&&i<str.value.length;i++){
if(this.value[i]!=str.value[i]){ return this.value[i]-str.value[i];} //返回两串第一个不同字符的差值

return this.value.length-str.value.length; //返回两串长度的差值


思路:
1.定义一个返回整数的函数
2.返回什么数由自己定义,比如这边返回的是两串第一个不同字符的差值
和返回两串长度的差值。

6.String的插入,删除操作。

String s1="Abcde", s2="Xyz";
int i=3;
String s3=s1.substring(o,i)+s2+s1.substring(i);
String s4=s3.substring(0,3)+s3.substring((6));

思路:
建立一个新的字符串,其构成分为几个部分,每个部分由substring从另外一个字符串得到我们想要的子串或者直接字符串,
进而完成插入和删除操作。

7.获得一个整数的二进制或十六进制形式字符串。

public static String toBinaryString(int n) //返回int整数的二进制字符串,除2取余法

String str="";
for(int i=0x80000000;i!=0;i>>>=1) //一个int占32位,右移一位,高位以0填充
str+=(n&i)==0?‘0‘:‘1‘;
return str; //返回字符串
}

public static String toHexString(int n) //返回正整数n的十六进制字符串

String str="";
while(n>0) //除16取余法,余法存入str字符串

int k=n%16;
str=(char)(k<=9?k+‘0‘:k+‘A‘-10)+str; //讲0~9,10~15转换为‘0‘~’9‘.‘A‘~‘F‘
n/=16;
}
return str;
}

//返回正整数n的radix进制字符串,tadix取值为2,8,16
public static String toString(int n,int radix)
{
String str="";
while(n>0) //除radix取余法,余数存入str字符串
{
int k=n%radix;
str=(char)(k<=9?k+‘0‘:k+‘A‘-10)+str;
n/=radix;
}
return str;
}

变量字符串类StringBuffer
引言:其以串变量方式实现字符串功能。其字符数组容量大于串长,并且能够修改,此时用一个整型变量len记载串的长度。串变量的插入,删除操作与线性表相似,
都要移动元素,但是对串的操作一次处理一个子串。
a.StringBuffer类声明
public final class MyStringBuffer implements java.io.Serializable //字符串类
{
private char[] value; //字符数组,私有成员变量
private int len; //串长度

public MySringBuffer(int size) //构造指定容量的空串
{
this.value=new char[size<16?16:size];
this.len=0;
}

public MyStringBuffer(){this(16);} //以默认容量构造空串
public MyStringBuffer(String str) //以字符串常量构造串对象
{
this(str.length()+16);
this.append(str);
}

//返回字符串长度,value.length是数组容量
public int length(){ return this.len;}
public synchronized char charAt(int i) //返回第i(i>=0)个字符
{
if(i<0||i>=this.len)
throw new StringIndexOutOfBoundsException(i);
return this.value[i];
}

public void setCharAt(int i,char ch) //设置第i个字符为ch
{
if(i<0||i>=this.len)
throw new StringIndexOutOfBoundsException(i);

this.value[i]=ch;
}

//以字符数组value从0至len元素构造String串
public synchronized String toString(){ return new String(this.value,0,this.len); }
}

以下为内部方法
1.插入串
public synchronized MyStringBuffer insert(int i,MyStringBuffer str) //在下标为i个字符处插入str串

if(i<0) i=0;
if(i>this.len) i=this.len; //序号容错

if(str=null){ return this;}

if(this.value.length-this.len<str.len) //若当前串数组空间不足,则扩充容量

this.value=new char[this.value.length+str.len*2]; //重新申请字符数组空间
for(int j=0;j<i;j++){ //复制当前串下标为前i-1个字符
this.value[j]=temp[j];


for(int j=i;j<this.len;j++)
this.value[str.len+j]=temp[j]; //从i开始向后移动j个字符

for(int j=0;j<str.len;j++) this.value[i+j]=str.value[j]; //复制字符串strs

this.len+=str.len;
return this;
}

思路
1.容错处理
2.容量不足处理,扩容(注意:最好选取this.value.length+str.len*2,完成了扩容又不会浪费内存)
3.复制下标i-1个字符,复制以前的i开始以后的字符,但是要移动j个字符。最后复制strs在i到i+j下标中。串长增加。
4.返回字符串

删除子串
public synchronized MyStringBuffer delete(int begin,int end) //删除序号从begin到end-1的子串
{
//序号容错
if(begin=<0){begin=0;} //从开头开始删除
if(end>this.len){ end=this.len;} //删除到结尾

if(begin>end) { throw new StringIndexOutOfBoundsException(end-begin);}

for(int i=0;i<this.len-end;i++){
this.value[begin+i]=this.value[end+i]; //下标为begin之后的开始的元素变成end之后的元素。
}
this.len-=end-begin;
return this;
}

思路:
1.容错处理
2.抛出异常处理
3.进行删除操作,下标为begin之后的开始的元素变成end之后的元素
4.改变串长
5.返回串

时间: 2024-08-23 11:46:08

串的基础的相关文章

串的基础操作

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo; color: #008000 } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px "PingFang SC"; color: #008000 } p.p3 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo; color: #0433ff } p.p4 {

Java反射基础笔记

由于工作中发现自己的基础知识掌握的并不是很牢固,遇到的问题与学习的东西也没有很好的做过记录,导致再遇到时耗费大量时间上网搜索,所以决定串下基础知识并尽量形成记录,方便自己之后遗忘时查询,也方便各位有需求的伙伴翻阅查看,大家共同探讨.学习. 本次梳理的是Java反射的基础,该系列为笔者学习慕课反射讲解视频的学习笔记,尽可能全的记录,以帮助初学者快速掌握反射基础知识,如需转载该系列请注明原文链接. 一.反射之Class类的使用 二.反射之获取方法信息 更多编辑中 --

关于回文串的DP问题

问题1:插入/删除字符使得原字符串变成一个回文串且代价最小 poj 3280 Cheapest Palindrome 题意:给出一个由m中字母组成的长度为n的串,给出m种字母添加和删除花费的代价,求让给出的串变成回文串的代价. Sol: 插入和删除等价,因此只需要保留 min(插入代价,删除代价)作为调整字符串的代价 如果 s[i]==s[j],那么将区间(i,j)变为回文串的代价和将区间(i+1,j-1)变为回文串的代价相同,因为此时不需要修改 如果不同,必然要将 s[i]和s[j]改为同一字

oc j基础

和果子   博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅  :: 管理     9 Posts :: 0 Stories :: 1 Comments :: 0 Trackbacks 公告 昵称:和果子园龄:1年6个月粉丝:6关注:3 +加关注 搜索 常用链接 我的随笔 我的评论 我的参与 最新评论 我的标签 我的标签 oc零基础(4) 面向对象(4) 数组排序(1) 字面量(1) socket(1) block(1) 字符串(1) 字典(1) tableView重用(1) table

替换字符串中的空格

题目描述: 请实现一个函数,将一个字符串中的空格替换成"%20".例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy. 输入: 每个输入文件仅包含一组测试样例. 对于每组测试案例,输入一行代表要处理的字符串. 输出: 对应每个测试案例,出经过处理后的字符串. 样例输入: We Are Happy 样例输出: We%20Are%20Happy -------------------------------------------------

【字符串】回文自动机资料

转自:http://blog.csdn.net/u013368721/article/details/42100363 今天我们来学习一个神奇的数据结构:Palindromic Tree.中译过来就是——回文树. 那么这个回文树有何功能? 假设我们有一个串S,S下标从0开始,则回文树能做到如下几点: 1.求串S前缀0~i内本质不同回文串的个数(两个串长度不同或者长度相同且至少有一个字符不同便是本质不同) 2.求串S内每一个本质不同回文串出现的次数 3.求串S内回文串的个数(其实就是1和2结合起来

结对编程任务的算法流程思路

这次的结对编程的作业相较于上次的作业看似只是核心功能的嫁接过程,但是程序这个东西尤其是对于实战经验并不很足的我来讲,其实还是很有难度的,因为在这次的作业要求中新加了很多的可以由用户定制的功能要求,那么以前的取巧一些的方法在对于这种可以随意定制功能的要求之下就显得力不从心,于是对我来讲这次的作业只有部分的算法的框架还留在程序中,从代码的角度来讲的话基本所有的代码都是被重构的,作为处女座的一员即便是当初可以用的代码,再一次复审的时候发现很多不和标准的地方的有悖于自己的强迫症的地方还是不能忍受的于是果

Codeforces Round #FF (Div. 2) 题解

比赛链接:http://codeforces.com/contest/447 A. DZY Loves Hash time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output DZY has a hash table with p buckets, numbered from 0 to p?-?1. He wants to insert n 

测试的艺术:代码检查、走查与评审

软件开发人员通常不会考虑的一种测试形式-人工测试. 大多数人都以为,因为程序是为了供机器执行而编写的,那么也该由机器来对程序进行测试.这种想法是有问题的.人工测试方法在暴露错误方面是很有成效的.实际上,大多数的软件项目都应使用到一下的人工测试方法: 1. 利用错误列表进行代码检查 2. 小组代码走查 3. 桌面检查 4. 同行评审 代码检查: 所谓代码检查是以组为单位阅读代码,它是一系列规程和错误检查技术的集合. 一个代码检查小组通常由四人组成: 协调人:以为称职的程序员 该程序的编码人员 该程