算法题:字符串处理

  • 题目一:替换空格

         【题目】

               请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

         【思路】

              注意题目是替换原来字符串

             1.替换字符串2.先确定原字符串中空格数3.设置字符串长度4.从后往前遍历,进行替换

         【解答】

public class Solution {
    public String replaceSpace(StringBuffer str) {
    int lengthOld=str.length();
    int spaceNum=0;
    for(int i=0;i<lengthOld;i++) {  //空格个数
    	if(str.charAt(i)==' ') {   //单引号表示字符
    		spaceNum++;
    	}
    }
    int lengthNew=lengthOld+spaceNum*2;
    str.setLength(lengthNew);
    int indexOld=lengthOld-1;
    int indexNew=lengthNew-1;
    for(;indexOld>=0 && indexOld<lengthNew;--indexOld) {   //&& 短路与  从后往前遍历
    	if(str.charAt(indexOld)==' ') {  
    		str.setCharAt(indexNew--, '0');
    		str.setCharAt(indexNew--, '2');
    		str.setCharAt(indexNew--, '%');
    	}else {
    		str.setCharAt(indexNew--, str.charAt(indexOld));
    	}
    }
    return str.toString();
    }
}
  • 题目二:正则表达式匹配

     

         【题目】

               请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配

         【思路】
 

解这题需要把题意仔细研究清楚,反正我试了好多次才明白的。

    首先,考虑特殊情况:

         1>两个字符串都为空,返回true

         2>当第一个字符串不空,而第二个字符串空了,返回false(因为这样,就无法

            匹配成功了,而如果第一个字符串空了,第二个字符串非空,还是可能匹配成

            功的,比如第二个字符串是“a*a*a*a*”,由于‘*’之前的元素可以出现0次,

            所以有可能匹配成功)

    之后就开始匹配第一个字符,这里有两种可能:匹配成功或匹配失败。但考虑到pattern

    下一个字符可能是‘*’, 这里我们分两种情况讨论:pattern下一个字符为‘*’或

    不为‘*’:

          1>pattern下一个字符不为‘*’:这种情况比较简单,直接匹配当前字符。如果

            匹配成功,继续匹配下一个;如果匹配失败,直接返回false。注意这里的

            “匹配成功”,除了两个字符相同的情况外,还有一种情况,就是pattern

            当前字符为‘.’,同时str的当前字符不为‘\0’。

          2>pattern下一个字符为‘*’时,稍微复杂一些,因为‘*’可以代表0个或多个。

            这里把这些情况都考虑到:

               a>当‘*’匹配0个字符时,str当前字符不变,pattern当前字符后移两位,

                跳过这个‘*’符号;

               b>当‘*’匹配1个或多个时,str当前字符移向下一个,pattern当前字符

                不变。(这里匹配1个或多个可以看成一种情况,因为:当匹配一个时,

                由于str移到了下一个字符,而pattern字符不变,就回到了上边的情况a;

                当匹配多于一个字符时,相当于从str的下一个字符继续开始匹配)

    之后再写代码就很简单了。

         【解答】

public class Solution{
    public boolean match2(char[] str, int i,char[] pattern,int j)
    {
        //先特殊
        if(i==str.length && j==pattern.length) {  // 字符串和模式串都为空
            return true;
        }else if(str.length!=i && pattern.length==j) {   // 模式串为空
            return false;
        }
        //后一般
        boolean next=(j+1<pattern.length && pattern[j+1]=='*');  // 模式串下一个字符是'*',j+1<=pattern.length?
        if(!next) {
            if(i<str.length && (pattern[j]==str[i]||pattern[j]=='.')) {     //i<=str.length?
                return match2(str,i+1,pattern,j+1);
            }else {
                return false;
            }
        }else {
            if(i<str.length && (pattern[j]==str[i]||pattern[j]=='.')) {
                return match2(str,i,pattern,j+2)||match2(str,i+1,pattern,j);   //?
            }else {
                return match2(str,i,pattern,j+2);
            }
             
        }
    }
    public boolean match(char[] str, char[] pattern) {
        return   match2(str,0,pattern,0);                                    //接收参数
    }
 
}
  • 题目三:表示数值的字符串

         【题目】

               请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。

         【思路】

                   正则

         【解答】

public class Solution {
	public boolean isNumeric(char[] str) {
	String str1=str.toString();
	//String regex1="(\\.\\d+)?(e\\d)*(\\dE)*";   //(e\\d)*(\\dE)-->([eE][\\+\\-]?\\d+)?
	//String regex2="((+-)|(-+))";                //((+-)|(-+))  -->[\\+\\-]? 
	String regex="[\\+\\-]?\\d*(\\.\\d+)?([eE][\\+\\-]?\\d+)?";
	
	以下对正则进行解释:
	[\\+\\-]?            -> 正或负符号出现与否
	\\d*                 -> 整数部分是否出现,如-.34, +3.34均符合
	(\\.\\d+)?           -> 如果出现小数点,那么小数点后面必须有数字;
	                        否则一起不出现
	([eE][\\+\\-]?\\d+)? -> 如果存在指数部分,那么e或E肯定出现,+或-可以不出现,
	                        紧接着必须跟着整数;或者整个部分都不出现
	
	if(str1.matches(regex)) {
		return true;
	}else {
		return false;
	}
}
}
  • 题目四:字符流中第一个不重复的字符

        【题目】

               请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。

         【思路】

                      使用int[ ]的下标或者hash 标记字符出先的次数

                      使用队列(先进先出),对字符出现的顺序进行判断

         【解答】

import java.util.LinkedList;
import java.util.Queue;
 
public class Solution{
    //Insert one char from stringstream
    int[] charCnt=new int[128];  //ASCII字符最多也就128个,用它的下标
    Queue<Character> queue=new LinkedList<Character>();
     
   int  i=0;   
   public void Insert(char ch)
   {
       if(charCnt[ch]++ ==0) {   //对应的索引位置,若charCnt[ch]!=0后,对应位置也会++
           queue.add(ch);
       }
   }
 //return the first appearence once char in current stringstream
   public char FirstAppearingOnce()
   {
      Character CHAR=null;
      char c=0;
      while((CHAR=queue.peek())!=null) {  //判断队列不是空的
          c=CHAR.charValue();
          if(charCnt[c]==1) {
              return c;
          }else {
              queue.remove();
          }
           
      }
      return '#';
   }
 
}
发布了11 篇原创文章 · 获赞 7 · 访问量 4012

猜你喜欢

转载自blog.csdn.net/wusimin432503/article/details/104609121
今日推荐