3.1 字符串移位包含问题
来源:互联网 发布:js页面大小改变事件 编辑:程序博客网 时间:2024/04/29 20:11
1. 前言
本文的一些图片, 资料 截取自编程之美
2. 问题描述
3. 问题分析
解法一 : 循环arr.length 次, 每次比较arr中是否包含目标字符串
如果不包含, 则将arr向右移动一位, 继续循环
否则 跳出循环 返回true
解法二 : 如果目标字符串是arr的循环移位子字符串, 那么目标字符串必定是 arr + arr, 的子字符串
当然在进入方法的时候, 需要对目标字符串 和arr的长度进行校验一下 避免一下情况 : 目标字符串为 : “aa”, arr 为 : “a”
4. 代码
/** * file name : Test03StringShiftContains.java * created at : 8:48:35 AM May 27, 2015 * created by 970655147 */package com.hx.test04;public class Test03StringShiftContains { // 判断src循环移位是否存在能够包含dst的子字符串 public static void main(String []args) { char[] src = new char[]{'a', 'b', 'b', 'c', 'd' }; char[] dst = new char[]{'c', 'd', 'a', 'b' }; stringShiftContains01(src, dst); stringShiftContains02(src, dst); } // 思路 如果src的长度小于dst的长度 则直接返回 因为无论src怎么移动 都不可能包含dst // 否则 判断src是否包含dst 如果不包含 则src向右移动一位 并再次判断 直到移动了src.length位 public static void stringShiftContains01(char[] src, char[] dst) { if(src.length < dst.length) { return ; } for(int i=0; i<src.length; i++) { if(contains(src, dst)) { Log.log("contains"); } rightShiftOnece(src); } } // 如果dst能够通过src循环移位得到 那么dst必然是src+src的子序列 // 如果src的长度小于dst的长度 则直接返回 因为无论src怎么移动 都不可能包含dst // 所以先构造一个char[]srcCopy 其内容为src + src 比如 src为"ab" srcCopy为"abab" // 然后 在判定srcCopy中是否包含dst public static void stringShiftContains02(char[] src, char[] dst) { if(src.length < dst.length) { return ; } char[] srcCopy = new char[src.length * 2]; System.arraycopy(src, 0, srcCopy, 0, src.length); System.arraycopy(src, 0, srcCopy, src.length, src.length); if(contains(srcCopy, dst) ) { Log.log("contains"); } } // 判断src中是否包含dst字符 private static boolean contains(char[] src, char[] dst) { return indexOf(src, dst) > 0; } // 获取src中dst的子字符序列的索引 // 先进行边界判定, 在循环找出src中和dst第一个字符相同的索引i, 在继续比较dst后面的子字符串 如果找到匹配的 则返回索引 // 否则 继续从(i+1)开始寻找 // 注 : 代码是从 String.indexOf(char[] src, char[]dst)中拷贝过来的 private static int indexOf(char[] src, char[] dst) { char[] source = src; char[] target = dst; int sourceOffset = 0, sourceCount = src.length; int targetOffset = 0, targetCount = dst.length; int fromIndex = 0; if (fromIndex >= sourceCount) { return (targetCount == 0 ? sourceCount : -1); } if (fromIndex < 0) { fromIndex = 0; } if (targetCount == 0) { return fromIndex; } char first = target[targetOffset]; int max = sourceOffset + (sourceCount - targetCount); for (int i = sourceOffset + fromIndex; i <= max; i++) { /* Look for first character. */ if (source[i] != first) { while (++i <= max && source[i] != first); } /* Found first character, now look at the rest of v2 */ if (i <= max) { int j = i + 1; int end = j + targetCount - 1; for (int k = targetOffset + 1; j < end && source[j] == target[k]; j++, k++); if (j == end) { /* Found whole string. */ return i - sourceOffset; } } } return -1; } // 将src中各个字符向右移动一位 private static void rightShiftOnece(char[] src) { char tmp = src[src.length-1]; for(int i=src.length-1; i>0; i--) { src[i] = src[i-1]; } src[0] = tmp; }}
5. 运行结果
6. 总结
这个问题, 对于第一种思路来说, 虽然想到非常容易, 但是效率并不高, 因为每一次都需要和dst进行一次contains操作
第二种思路 是比较巧妙的
我个人的想法是, 将原字符串的元素做成一个循环单链表, 最后一个元素.next 接到第一个元素, 这样, 然后在查找子串, 当然和上面的第二种思路 基本上是一致的, 当然 也需要进行长度的校验
注 : 因为作者的水平有限,必然可能出现一些bug, 所以请大家指出!
0 0
- 3.1字符串移位包含问题
- 3.1 字符串移位包含问题
- 3.1 字符串移位包含问题
- 字符串移位包含问题
- 字符串移位包含问题
- 字符串移位包含问题
- 字符串移位包含问题
- 字符串移位包含问题
- 字符串移位包含问题
- 字符串移位包含问题
- 字符串移位包含问题
- 字符串移位包含问题
- 字符串移位包含问题
- 字符串移位包含问题
- 字符串移位包含问题
- 字符串移位包含问题
- 字符串移位包含问题
- 字符串移位包含问题
- LeetCode题解——Combination Sum III
- 第4组UI-ProgressBar及子类之ProgressBar(进度条)、SeekBar(拖动条)和RatingBar(星级评分条)
- C语言实现Split函数
- C内存操作函数
- [MachineLearningInAction] - KNN
- 3.1 字符串移位包含问题
- 测量webView页面性能技术方案
- 事件驱动仿真
- poj4474 枚举
- C++类库:OTL连接MySQL ODBC数据库(insert, update, select)
- RGCDQ (HDU5317)
- Maven-Missing artifact 的解决办法
- 如何算音频PTS
- Ubuntu MySQL允许远程连接数据库访问