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];
			}
		}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;
	}


 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jun-H

你的鼓励是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值