日期:2014-05-16  浏览次数:20517 次

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-begin
		int 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];
			}
		}els