Java 实现PDB数据库中蛋白质部分序列与Uniport数据库中相应的全长序列的最优匹配
/** * @param strArr数组的第一维是部分序列,第二维是全长序列 * @return 返回时两个大部分对齐后的部分和全长序列, 若返回null时则表示, 程序对齐失败 * @function 程序主要是实现经过处理后的蛋白质部分序列与全长序列的对齐, * 忽略每个氨基酸前后MW(最小窗口)中间的一些小的不一样的氨基酸, 部分序列中可以加空格, 全长序列中不能加空格 * @notice 在某种情况下程序可能会失效 */public static String[] AlignTwoProteinSeqIgnoreLittleMistakeInMW(String partSeq, String fullSeq){final int MW = 10;// 表示前后窗口的大小final int lW = 3;// 表示在前后窗口中最多能容忍几个错误final int MFPreSpaceNum = 3;//表示全长序列前面最多加多少空格 StringBuffer partAns = new StringBuffer(partSeq.toUpperCase());StringBuffer fullAns = new StringBuffer(fullSeq.toUpperCase());int fullPreSpaceNum = 0;boolean isFirstMatch = false; //标记第一次是否能对其for (int i = 0; ; i++){ //Seq是在变动的partSeq = partAns.toString();fullSeq = fullAns.toString();String prePI = mySubString(partSeq, i-MW, i);String afterPI = mySubString(partSeq, i+1, i+1+MW);String preFI = mySubString(fullSeq, i-MW, i);String afterFI = mySubString(fullSeq, i+1, i+1+MW);int preNSAcidNum = statisticNotSameAcidNum(prePI, preFI);int afterNSAcidNum = statisticNotSameAcidNum(afterPI, afterFI);if (fullSeq.charAt(i) == partSeq.charAt(i)){ //当前氨基酸是一样的//如果后面的窗口不可以匹配, 则我们要根据前面的窗口判断是前面加空格if (lW < afterNSAcidNum){ if (lW < preNSAcidNum){System.out.println("这是不会出现的错");System.exit(-1);}else{if (prePI.charAt(MW - 1) == ' '){ //在前面加空格partAns.delete(0, partAns.length());partAns.append(partSeq.substring(0, i));partAns.append(" ");partAns.append(partSeq.substring(i, partSeq.length()));}}}else{// 判断是不是第一次匹配int afterFISpaceNum = 0;for (int kkk = 0; kkk < afterFI.length(); kkk++){if (' ' == afterFI.charAt(kkk)){afterFISpaceNum++;}}if (lW >= afterFISpaceNum)isFirstMatch = true;}}else{//当前氨基酸是不一样的if (lW < afterNSAcidNum){ //如果后面的不可以匹配partAns.delete(0, partAns.length());partAns.append(partSeq.substring(0, i));partAns.append(" ");partAns.append(partSeq.substring(i, partSeq.length()));}else{ //如果后面的可以匹配就匹配// 判断是不是第一次匹配int afterFISpaceNum = 0;for (int kkk = 0; kkk < afterFI.length(); kkk++){if (' ' == afterFI.charAt(kkk)){afterFISpaceNum++;}}if (lW >= afterFISpaceNum)isFirstMatch = true;}}// 判断是否匹配成功String temp = mySubString("", 0-MW, 0);if (afterPI.equals(temp) || afterFI.equalsIgnoreCase(temp)){ if (!isFirstMatch){fullPreSpaceNum++;if (MFPreSpaceNum + 1 <= fullPreSpaceNum){return null;}fullAns.delete(0, fullAns.length());fullAns.append(" ");fullAns.append(fullSeq);i = fullPreSpaceNum - 1;partAns.delete(0, partAns.length()); //略去中间产生的无用空格for (int lll = 0; lll < partSeq.length(); lll++){if (' ' != partSeq.charAt(lll)){partAns.append(partSeq.charAt(lll));}}}else{break;}}}return partAns.append("#" + fullAns.toString()).toString().split("#");}public static String mySubString(String srcStr, int begin, int end){//没有的部分我们用空格表示 保证返回的字符串长度为end-beginint len = srcStr.length();byte[] srcArr = srcStr.getBytes();byte[] ans = new byte[end - begin];for (int i = 0; i < end - begin; i++) ans[i] = ' ';if (begin < 0 && end <= len){begin = 0;for (int i = end - 1, j = ans.length - 1; i >= begin; i--, j--){ans[j] = srcArr[i];}}else if (end > len && begin >= 0){end = len;for (int i = begin, j = 0; i < end; i++, j++){ans[j] = srcArr[i];}}else if (begin >=0 && end <= len){for (int i = begin, j = 0; i < end; i++, j++){ans[j] = srcArr[i];}}else if(begin < 0 && end > len){for (int i = 0, j = 0 - begin; i < len; i++, j++){ans[j] = srcArr[i];} }return new String(ans);}public static int statisticNotSameAcidNum(String lineone, String linetwo){byte[] oneArr = lineone.toUpperCase().getBytes(); //忽略氨基酸的大小写byte[] twoArr = linetwo.toUpperCase().getBytes();if (oneArr.length != twoArr.length){System.out.println("two line not the same lenght!");return -1;}int ans = 0;for (int i = 0; i < oneArr.length; i++){if (oneArr[i] != twoArr[i] && ' ' != oneArr[i] && ' ' != twoArr[i]){ans++;}}return ans;}