编程题Tip

来源:互联网 发布:矩阵分解推荐算法 编辑:程序博客网 时间:2024/05/23 05:06

字符串中的回文串问题:

一、字符串是否为回文串

public class HuiWenTest {  /**  * @SERLIN 将字符串倒置后逐一比较 */  public static void main(String[] args) {      String str = "";      System.out.println("请输入一个字符串");      Scanner input = new Scanner(System.in);      str = input.next();        StringBuffer sb = new StringBuffer(str);      sb.reverse();// 将Str中的字符串倒置        int count = 0;      for (int i = 0; i < str.length(); i++) {          if (str.charAt(i) == sb.charAt(i)) {              count++;          }      }      if (count == str.length()) {                    System.out.println("此字符串是一个回文字符串");      } else {          System.out.println("此字符串不是一个回文字符串");      }  }  


public class HuiWenTest2 {      /**      * @SERLIN 将字符串倒置后创建一个新的原字符串比较     */      public static void main(String[] args) {          System.out.println("请输入一个字符串");          Scanner input = new Scanner(System.in);          String str = input.next();          StringBuilder sb=new StringBuilder(str);          sb.reverse();//将str倒置的方法          String newStr=new String(sb);          if(str.equals(newStr)){              System.out.println(str+"是回文字符串");          }else{              System.out.println(str+"不是回文字符串");          }      }  }  

public class HuiWenTest3 {      /**      * @SERLIN 使用截取字符串的方式比较     */      public static void main(String[] args) {          System.out.println("请输入一个字符串");          Scanner input = new Scanner(System.in);          String str = input.next();          int count = 0;          for (int i = 0; i < str.length() / 2; i++) {          if ((str.substring(i, i + 1)).equals(str.substring(str.length() - 1- i, str.length() - i))) {                  count++;              }          }          if (count == str.length() / 2) {              System.out.println("是回文字符串");          }else{              System.out.println("不是回文字符串");          }      }  }  

public class HuiWenNum {      /**      * @SERLIN判断回文数字(判断纯数字)     */      public static void main(String[] args) {          int n;          System.out.println("请输入一个整数:");           // 如果结果为回文数,跳出循环          while (true) {              Scanner InpuNum = new Scanner(System.in);              n = InpuNum.nextInt();              if (isHuiWen(n)) {                  System.out.println(n + "是回文数!");                  break;              } else {                  System.out.println(n + "不是回文数!");              }          }      }          // 判断的数字是否是回文数      public static boolean isHuiWen(int n) {          int m = reverse(n);          if (m == n) {              return true;          } else {              return false;          }      }          // 将输入的数字进行倒置,以便进行判断是否是回文数      public static int reverse(int n) {          int temp = 0;// 临时变量          int j = 0;// 倒置后的数字          temp = n;// 将输入的数字赋值给临时变量          while (temp != 0) {              j = j * 10 + temp % 10;              temp /= 10;          }          return j;      }  }  

二、求给定的字符串中最长的子回文串

1,最简单直接的想法就是:找出字符串的所有子串,然后判断每一个子串是否是回文,并记录,比较求出最大长度的回文,

*算法时间复杂度为O(n^3)。例如,给定字符串String T="google",如何求其最长的回文子字符串"goog"

/*  * 4,求最长回文子串  *问题描述:给定一个字符串求出其所有子串中最长的回文子串,例如google字符串,最长子串为goog  *分析:  *1,最简单直接的想法就是:找出字符串的所有子串,然后判断每一个子串是否是回文,并记录,比较求出最大长度的回文  *算法时间复杂度为O(n^3)  */  public String longestPalindrome1(String s){      String result=null;      String tempString="";      //定义最长回文子串的长度      int max=0;      //遍历字符串中的所有元素      for(int i=0;i<s.length();i++){          //数组下标指针j从字符串后面开始往前遍历          for(int j=s.length()-1;j>i;j--){              //判断每一个字符串时候为回文              tempString=s.subStr( i, j+1);              //如果tempString是回文子串并且其长度(j-i+1)>max              if(isPalindrome(tempString)&&(j-i+1)>max){                  max=j-i+1;                  result=subString(i, j+1);              }          }      }      return result;  }  /*      * 3:      * 回文判断      * 问题描述:回文,英文palindrome,指一个顺着读和反过来读都一样的字符串,比如madam、我爱我,      * 方法一:      * 分析:使用两个"指针"分别从字符串头和尾扫描,若每一个"指针"所指值都相等,这为回文      */      public boolean isPalindrome(String s){          if(s==null)              return false;          int left=0;          int right=s.length()-1;          while(left<right){              if(s.charAt(left)!=s.charAt(right))                  return false;              left++;              right--;          }          return true;      }  


/*第二种思路就是对于字符串中的每一个字符T[i],判断 以T[i],T[i+1]为中心的偶数长度子字符串是回文T[i]为中心的奇数长度子字符串是否是回文
public String longestPalindrome2(String T){          String result=null;          //存放最大回文字符串的长度          int max=0;          //遍历每一个字符,以每一个字符为中心判断奇偶扩展子串          for(int i=0;i<T.length();i++){              //定义两个数组下标指针,以i,i+1为中心的偶子序列              int pStart=i;              int pEnd=i+1;              while(pStart>=0&&pEnd<=(T.length()-1)&&T.charAt(pStart)==T.charAt(pEnd)){                  pStart--;                  pEnd++;              }              //如果子字符串的长度>max,则暂存为最长子回文串  子回文串的长度=(pEnd-1)-(pStart+1)-1=pEnd-pStart-1              if(pEnd-pStart-1>max){                  max=pEnd-pStart-1;                  result=subString( pStart+1, pEnd-1+1);              }                            //以i为中心,判断扩展奇序列是否为回文串              pStart=i-1;              pEnd=i+1;              while(pStart>=0&&pEnd<=(T.length()-1)&&T.charAt(pStart)==T.charAt(pEnd)){                  pStart--;                  pEnd++;              }              if (pEnd-pStart-1>max) {                  max=pEnd-pStart-1;                  result=subStrint(T, pStart+1, pEnd-1+1);              }          }          return result;      }  


//Manacher算法 时间复杂度为O(n)public static int getPalindromeLength(String str) {// 1.构造新的字符串// 为了避免奇数回文和偶数回文的不同处理问题,在原字符串中插入'#',将所有回文变成奇数回文StringBuilder newStr = new StringBuilder();newStr.append('#');for (int i = 0; i < str.length(); i++) {newStr.append(str.charAt(i));newStr.append('#');}// rad[i]表示以i为中心的回文的最大半径,i至少为1,即该字符本身int[] rad = new int[newStr.length()];// right表示已知的回文中,最右的边界的坐标int right = -1;// id表示已知的回文中,拥有最右边界的回文的中点坐标int id = -1;// 2.计算所有的rad// 这个算法是O(n)的,因为right只会随着里层while的迭代而增长,不会减少。for (int i = 0; i < newStr.length(); i++) {// 2.1.确定一个最小的半径int r = 1;if (i <= right) {r = Math.min(rad[id] - i + id, rad[2 * id - i]);}// 2.2.尝试更大的半径while (i - r >= 0 && i + r < newStr.length() && newStr.charAt(i - r) == newStr.charAt(i + r)) {r++;}// 2.3.更新边界和回文中心坐标if (i + r - 1 > right) {right = i + r - 1;id = i;}rad[i] = r;}// 3.扫描一遍rad数组,找出最大的半径int maxLength = 0;for (int r : rad) {if (r > maxLength) {maxLength = r;}}return maxLength - 1;}




Manacher算法详细讲解链接http://blog.sina.com.cn/s/blog_3fe961ae0101iwc2.html


 
原创粉丝点击