第五届在线编程大赛月赛指定题目:反向互补子串

第五届在线编程大赛月赛指定题目:反向互补子串
返回首页

  • 发布公司:
  • 有 效 期:
  • CSDN
  • 2014-06-132015-06-13
  • 难 度 等 级:
  • 答 题 时 长:
  • 编程语言要求:
  • 120分钟
  • C C++ Java C#
悬赏详情
一等奖 : 价值4999的诺基亚Lumia1020手机一台。 
二等奖 : 价值799的平板电脑一台。 
三等奖 : 价值199的移动电源一个。 
题目详情

这是个字符串问题。我们的字符串只包含大写字母。我们定义一个字母和它13位以后的字母互补。即A与N互补,B与O互补,C与P互补……,我们需要找一个字符串的两个不重叠的子串,其中一个和另外一个的翻转全互补。另外,因为我们的问题来自生物学,所以我们允许这两个字符串的一个可以删掉两个字符(注意:仅允许一个字符串删掉任意位置的两个字符,另外一个必须全部互补上)。我们的目的是求最长的反向互补子串的长度。

输入格式:

多组数据,每组数据一行,有一个字符串。每个字符串长度不超过2000,只有大写英文字母组成。

输出格式:

每组数据输出一行包含一个整数,表示最长的反向互补子串长度。

答题说明


输入样例

ABCD

ABCDQOPN

ABON

输出样例:

0

2

2

解释:

第一个样例,没有互补的子串。

第二个样例,AB和NO互补,所以反向互补子串的时候我们可以选择NPO,删掉一个P即可。

第三个样例,AB与ON反向互补。



源码如下,虽然自己跑着没问题,但是提交代码测试后,居然说“通常错误,数组越界”,不知咋回事,以后有时间再看吧。

public class Main {
	private static List<String> stringList = new ArrayList<String>();
	public static void main(String[] args) {
		Scanner sc = null;
		int count = 0;
		while (count < 3){
			sc = new Scanner(System.in);
			String string = sc.nextLine();
			stringList.add(string);
			count++;
		};
		sc.close();
		
		for (String testString : stringList) {
			int max = 0;
			char[] array = testString.toCharArray();
			SubString subString = new SubString();
			List<SubString> subStringList = new ArrayList<SubString>();
			int index = 0;
			while (index < array.length) {
				int temp = index;
				a: while (temp < array.length) {
					subString.addLocation(temp);
					char oppositeChar = 0;
					if (testString.contains(((char) (array[temp] + 13)) + "")) {
						oppositeChar = (char) (array[temp] + 13);
					} else if (testString.contains(((char) (array[temp] - 13))
							+ "")) {
						oppositeChar = (char) (array[temp] - 13);
					}
					List<Integer> list = getCharacterPosition(oppositeChar,
							testString);
					if (list.size() == 0) {
						subStringList.clear();
						subString.emptyCount = 0;
						subString.locationList.clear();
						temp++;
						continue;
					}
					if (subStringList.size() <= 0) {
						for (int i = 0; i < list.size(); i++) {
							SubString subString1 = new SubString();
							subString1.addLocation(list.get(i));
							subStringList.add(subString1);
						}
					} else {
						for (int i = 0; i < subStringList.size(); i++) {
							if (subString.getLength() != subStringList.get(i)
									.getLength() + 1) {
								continue;
							}
							for (int j = 0; j < list.size(); j++) {
								int last = subStringList.get(i).getLastLoc();
								c: for (int k = 0; k < 3 - subStringList.get(i).emptyCount; k++) {
									if (last - k - 1 == list.get(j)
											&& (last - k - 1 > subString
													.getLastLoc() || subStringList
													.get(i).getFirstLoc() < subString
													.getFirstLoc())) {
										subStringList.get(i).emptyCount = k
												- 1
												+ subStringList.get(i).emptyCount;
										subStringList.get(i).addLocation(
												list.get(j));
										break c;
									}
								}
							}
						}
					}

					boolean bool = false;
					for (int i = 0; i < subStringList.size(); i++) {
						if (subString.getLength() == subStringList.get(i)
								.getLength()) {
							bool = true;
						}
						max = max < subStringList.get(i).getLength() ? subStringList
								.get(i).getLength() : max;
					}
					if (!bool) {
						subStringList.clear();
						subString.remove();
						subString.emptyCount = 0;
						subString.locationList.clear();
						break a;
					}
					temp++;
				}
				index++;
			}
			System.out.println(max);
		}
	}

	public static List<Integer> getCharacterPosition(char c, String string) {
		List<Integer> list = new ArrayList<Integer>();
		Matcher slashMatcher = Pattern.compile(c + "").matcher(string);
		while (slashMatcher.find()) {
			list.add(slashMatcher.start());
		}
		return list;
	}

	static class SubString {
		public String string;
		public int emptyCount;
		public List<Integer> locationList = new ArrayList<>();

		public void addLocation(int loc) {
			locationList.add(loc);
		}

		public int getFirstLoc() {
			return locationList.get(0);
		}

		public int getLastLoc() {
			return locationList.get(locationList.size() - 1);
		}

		public int getLength() {
			return locationList.size();
		}

		@Override
		public String toString() {
			// TODO Auto-generated method stub
			StringBuffer string = new StringBuffer();
			for (int i = 0; i < locationList.size(); i++) {
				string.append(locationList.get(i) + ",");
			}
			return string.toString();
		}

		public void remove() {
			if (locationList.size() > 0) {
				locationList.remove(locationList.size() - 1);
			}
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值