回环变位(2017校招一模-----循环单词)

今天在算法4中看到了一个回环变位,觉得好高大上,由于才开始学习的算法,我也是抱着虚心学习的态度,打算实现一下,顺便看到了2017校招一模的第二个编程题就是回环变位的变形,下面细说一二。
题目是这样滴:

如果字符串s中的字符循环转移任意位置之后得到一个新的字符串t,那么s就被称为t的回环变位(circular rotation),例如ACTGACG就是TGACGAC的一个回环变位,反之亦然判定这个条件在基因组序列的研究中是很重要的,编写一个程序检查给定的字符串s和t是否互为回环变位

提示:答案只需要一行用到index(),length()和字符串连接的代码
由于对java字符串API不是十分了解,所以先想到了拆分遍历再合并的方法。
今天在牛客中学习了一会,我的两种方法的实现:
*第一种方法是:将一个字符串写两遍,比如else,写两遍elseelse,则取定长的4位为所有的变换子循环单词。 即else,lsee,seel,eels

  package com.niuke.algorithms;

/**
 * @author 康师傅没有眼泪
 * @data 2017年6月6日 上午12:07:23
 * 第二种方法是想将字符串写两次,定长截取做判断
 *  (s.length() == t.length()&&(s.concar(s).indexOf()))
 */
public class StringOperationDemo {
	public static void main(String args[]){
		String s1 = "actgacg";
		String s2 = "tgacgac";
		if(s1.length() == s2.length() && (s1.concat(s1).indexOf(s2)) >=0 )
			System.out.println("s1,s2互为回环变位");
		else
			System.out.println("s1,s2不是回环变位");
	}
}

*第二种方法是:把字符串最右边的的字符移动到最左边
即eels,一个循环右移即可。

 package com.niuke.algorithms;
/**
 * @author 康师傅没有眼泪
 * @data 2017年6月4日 下午5:52:16
 *      只用到一行的代码实现
 *      (s.length() == t.length()&&(s.concar(s).indexOf())) 我很无语
 */
public class CircularRotation {
	public static void main(String args[]){
		String s1 = "word";
		String s2 = "ordw";
		if(isCircularRotation(s1,s2)){
			System.out.println("s1,s2互为回环变位");
		}else{
			System.out.println("s1,s2不是互为回环变位");
		}
		
	}
	public static boolean isCircularRotation(String s,String t){
		if(s.length() != t.length()){
			return false;
		}else{			
			for(int i = 1; i <= s.length(); i++){
				String left = s.substring(0, i);
				String right = s.substring(i, s.length());		
				if((right+left).equals(t)){
					return true;
				}
			}
		}
		return false;
	}
}

2017校招一模的第二个编程题就是回环变位的变形

题目是这样滴: 如果一个单词通过循环右移获得的单词,我们称这些单词都为一种循环单词。 例如:picture 和 turepic
就是属于同一种循环单词。 现在给出n个单词,需要统计这个n个单词中有多少种循环单词。 输入描述: 输入包括n+1行:
第一行为单词个数n(1 ≤ n ≤ 50) 接下来的n行,每行一个单词word[i],长度length(1 ≤ length ≤
50)。由小写字母构成

输出描述: 输出循环单词的种数

输入例子: 5 picture turepic icturep word ordw

输出例子: 2

以下为代码实现:

package com.stringoperation.algorithms;

import java.util.ArrayList;
import java.util.Scanner;

/**
 * @author 康师傅没有眼泪
 * @data 2017年6月4日 下午6:15:53
 *  
 */
public class MainTest {
	 public static void main(String[] args) {
		 int N=50;
	        Scanner sc = new Scanner(System.in);
	        N = sc.nextInt(); //第一行为单词个数N
	        ArrayList<String> list = new ArrayList<>();
	        int count = 0;
	        for (int i = 0; i < N; i ++) {
	            String s = sc.next(); //输入并存储每行的单词。此处必须调用next()方法
	            if (!list.contains(s)) {
	                count ++;
	                list.add(s);
	                for (int j = 0; j < s.length() - 1; j ++) {
	                    //以下注释是另一种方法,把可能的循环单词加入list,
	                    //思路:把要测试的单词后再重复下这个单词,如:word ,变成 wordword
	                    String st r = new String();
	                	str = s.concat(s);
/*                    str.append(s); 
                      sb.insert(sb.length(), x) 都可实现,用StringBuffer类即可实现
                   str.append(s); sb.insert(sb.length(), x) */
	                    String b = str.substring(j, s.length() + j);
	                    list.add(b);
	                }
	            }
	        }
	        System.out.println(count);
	    }
}

最后附上已知字符串S逆序的递归实现方式

public static String mystery(String s){
	int N=s.length();
	String s1 = s.substring(0, N/2);
	String s2 = s.substring(N/2, N);
	return mystery(s2) + mystery(s1);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

阿龙先生啊

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值