首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 如何查找两个字符串中是否有相同的子串 [已结贴,结贴人:bangbong]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-07-03 11:48:39 楼主
    假设有两个字符串 strA 和 strB ,长度都大于1(即不是单个字符的“字符串”),而且都比较长,现在想写一个方法,对它们进行比较查找,看看它们是否有相同的子字符串,有就返回true,没有就返回false。注意:查找目标是相同的“子字符串”,相同的单个字符不算!

    例:

    "abcdefgh" 和 "hijklmn" ,虽然都有h字符,但是因为只是单个字符,所以不算包含相同子字符串,返回false

    "abcdefgh" 和 "adidas" ,虽然都有a、d字符,但是因为在前者中a、d是分开的,并不是连续的字符串,所以也不算包含相同子字符串,返回false

    "abcdefgh" 和 "cdilopty" ,它们都包含有字符串cd,所以应该返回true

    "abcd" 和 "hiabcdpo" ,一个包含另一个整个字符串,也算有相同的子字符串,返回true


    简单说就是判断两个字符串有没有公共子串
    -----------------------------------------------------------------------------
    求教各位达人,有没有什么简单的算法实现此功能?如果写代码,最好是Java的,C++的也行吧,我自己看懂再改写成Java
    20  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-07-03 11:48:441楼 得分:0
    此回复为自动发出,仅用于显示而已,并无任何其他特殊作用
    楼主【bangbong】截止到2008-07-03 11:48:59的历史汇总数据(不包括此帖):
    发帖的总数量:5                        发帖的总分数:30                     
    结贴的总数量:5                        结贴的总分数:30                     
    无满意结贴数:3                        无满意结贴分:50                     
    未结的帖子数:0                        未结的总分数:0                       
    结贴的百分比:100.00%              结分的百分比:100.00%                 
    无满意结贴率:60.00 %              无满意结分率:166.67%                 
    敬礼!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-07-03 11:54:012楼 得分:0
    跟你讲个思路吧。。。先比较两个字符串的长度。。。取长度短的那个字符串A,长的为B
    取A字符串的前两个字符(然后2和3,一次类推),到B中查找有没有,有返回TRUE,没有返回FALSE;
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-07-03 11:54:293楼 得分:0
    貌似数据结构里面有一个算法
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-07-03 12:14:544楼 得分:0
    Java code
    Boolean bool = false; String a = "aldjfkld"; String b = "fjdkjfd"; int lena = a.length(); for(int i = 0; i < lena - 1; i++) { String c = a.substring(i, i + 2); int t = b.indexOf(c); if(t != -1) { bool = true; break; } } System.out.println(bool);
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-07-03 12:31:395楼 得分:0
    如果全部是字母,都比较长可以考虑这样的优化
    Java code
    String a = "abcdefgh"; String b = "hijklmn"; boolean[][] grid = new boolean[26][26]; for(int i = 0; i < a.length() - 1; i++) grid[a.charAt(i) - 'a'][a.charAt(i + 1) - 'a'] = true; boolean found = false; for(int i = 0; i < b.length() - 1; i++) if(grid[b.charAt(i) - 'a'][b.charAt(i + 1) - 'a']) { found = true; } System.out.println(found);
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • craky
    • 等级:
    发表于:2008-07-03 12:32:286楼 得分:0
    Java code
    /** * 比较两个字符串是否含有共同的子字符串 * @param str1 字符串一 * @param str2 字符串二 * @param includeSelf 子字符串是否包括本身 * @return 比较结果 */ public static boolean hasSameSubStr(String str1, String str2, boolean includeSelf) { String shortStr = str1.length() > str2.length()? str2: str1; String longStr = str1.length() > str2.length()? str1: str2; String temp = ""; for(int i = 0; i < shortStr.length(); i++) { for(int j = i + 2; j <= shortStr.length(); j++) { temp = shortStr.substring(i, j); if(includeSelf && longStr.indexOf(temp) > 0) { return true; } else if(!includeSelf && !temp.equals(shortStr) && longStr.indexOf(temp) > 0) { return true; } } } return false; }
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-07-03 12:32:457楼 得分:0
    如果有大小写,则将grid改成 [52][52]再处理一下
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-07-03 12:33:308楼 得分:0
    如果现在将要求提高一些,不仅要求判断是否有共同子串,而且要求得到它们最长的共同子串呢?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • craky
    • 等级:
    发表于:2008-07-03 12:47:149楼 得分:0
    引用 8 楼 bangbong 的回复:
    如果现在将要求提高一些,不仅要求判断是否有共同子串,而且要求得到它们最长的共同子串呢?


    Java code
    /** * 获取两个字符串的最大的子字符串集合 * @param str1 字符串一 * @param str2 字符串二 * @param includeSelf 子字符串是否包括本身 * @return 最大的子字符串集合 */ public static List<String> getMaxSameSubStr(String str1, String str2, boolean includeSelf) { String shortStr = str1.length() > str2.length()? str2: str1; String longStr = str1.length() > str2.length()? str1: str2; String temp = ""; int subLength = 0; List<String> sameSubs = new ArrayList<String>(); for(int i = 0; i < shortStr.length(); i++) { for(int j = i + 2; j <= shortStr.length(); j++) { temp = shortStr.substring(i, j); boolean flag1 = includeSelf && longStr.indexOf(temp) > 0; boolean flag2 = !includeSelf && !temp.equals(shortStr) && longStr.indexOf(temp) > 0; if(flag1 || flag2) { if(temp.length() > subLength) { sameSubs.clear(); sameSubs.add(temp); } else if(temp.length() == subLength) { sameSubs.add(temp); } subLength = temp.length(); } } } return sameSubs; }
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • craky
    • 等级:
    发表于:2008-07-03 12:55:3910楼 得分:0
    两个功能合在一起就是

    Java code
    /** * 比较两个字符串是否含有子字符串,如果有,获取最大的子字符串集合 * 返回值为List,长度为2,第一个元素为boolean型,表示是否含有子字符串,第二个元素为List<String>,表示最大子字符串的集合 * @param str1 字符串一 * @param str2 字符串二 * @param includeSelf 是否包括自身 * @return 比较结果 */ public static List<Object> compareStrWithSub(String str1, String str2, boolean includeSelf) { String shortStr = str1.length() > str2.length()? str2: str1; String longStr = str1.length() > str2.length()? str1: str2; String temp = ""; int subLength = 0; boolean hasSame = false; List<String> sameSubs = new ArrayList<String>(); List<Object> ret = new ArrayList<Object>(); for(int i = 0; i < shortStr.length(); i++) { for(int j = i + 2; j <= shortStr.length(); j++) { temp = shortStr.substring(i, j); boolean flag1 = includeSelf && longStr.indexOf(temp) > 0; boolean flag2 = !includeSelf && !temp.equals(shortStr) && longStr.indexOf(temp) > 0; if(flag1 || flag2) { hasSame = true; if(temp.length() > subLength) { sameSubs.clear(); sameSubs.add(temp); } else if(temp.length() == subLength) { sameSubs.add(temp); } subLength = temp.length(); } } } ret.add(hasSame); ret.add(sameSubs); return ret; }
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-07-03 12:57:3011楼 得分:0
    那个是lcs算法,动态规划思想的
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • craky
    • 等级:
    发表于:2008-07-03 13:17:4812楼 得分:0
    大意了大意了,9楼、10楼的有点小问题,正确的如下

    Java code
    /** * 获取两个字符串的最大的子字符串集合 * @param str1 字符串一 * @param str2 字符串二 * @param includeSelf 子字符串是否包括本身 * @return 最大的子字符串集合 */ public static List<String> getMaxSameSubStr(String str1, String str2, boolean includeSelf) { String shortStr = str1.length() > str2.length()? str2: str1; String longStr = str1.length() > str2.length()? str1: str2; String temp = ""; int subLength = 0; List<String> sameSubs = new ArrayList<String>(); for(int i = 0; i < shortStr.length(); i++) { for(int j = i + 2; j <= shortStr.length(); j++) { temp = shortStr.substring(i, j); boolean flag1 = includeSelf && longStr.indexOf(temp) > 0; boolean flag2 = !includeSelf && !temp.equals(shortStr) && longStr.indexOf(temp) > 0; if(flag1 || flag2) { if(temp.length() > subLength) { subLength = temp.length(); sameSubs.clear(); sameSubs.add(temp); } else if(temp.length() == subLength) { sameSubs.add(temp); } } } } return sameSubs; } /** * 比较两个字符串是否含有子字符串,如果有,获取最大的子字符串集合 * 返回值为List,长度为2,第一个元素为boolean型,表示是否含有子字符串,第二个元素为List<String>型,表示最大子字符串的集合 * @param str1 字符串一 * @param str2 字符串二 * @param includeSelf 是否包括自身 * @return 比较结果 */ public static List<Object> compareStrWithSub(String str1, String str2, boolean includeSelf) { String shortStr = str1.length() > str2.length()? str2: str1; String longStr = str1.length() > str2.length()? str1: str2; String temp = ""; int subLength = 0; boolean hasSame = false; List<String> sameSubs = new ArrayList<String>(); List<Object> ret = new ArrayList<Object>(); for(int i = 0; i < shortStr.length(); i++) { for(int j = i + 2; j <= shortStr.length(); j++) { temp = shortStr.substring(i, j); boolean flag1 = includeSelf && longStr.indexOf(temp) > 0; boolean flag2 = !includeSelf && !temp.equals(shortStr) && longStr.indexOf(temp) > 0; if(flag1 || flag2) { hasSame = true; if(temp.length() > subLength) { subLength = temp.length(); sameSubs.clear(); sameSubs.add(temp); } else if(temp.length() == subLength) { sameSubs.add(temp); } } } } ret.add(hasSame); ret.add(sameSubs); return ret; }
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-07-03 13:41:4713楼 得分:5
    Java code
    public class lcs { /** * @param args */ private static String string1 = "acdegfgggwwwww"; private static String string2 = "bcdefgggqq"; public static void searchlcs(char[] char1, char[] char2) { int[][] result = new int[char1.length+1][char2.length+1]; for(int i = 0; i < char1.length; i++) result[i][0] = 0; for(int j = 0; j < char2.length; j++) result[0][j] = 0; int maxLength = 0; int maxPosX = 0; int maxPosY = 0; for(int i = 0; i < char1.length; i++) for(int j = 0; j < char2.length; j++) if(char1[i] == char2[j]) { result[i+1][j+1] = result[i][j] + 1; if(result[i+1][j+1] > maxLength) { maxLength = result[i+1][j+1]; maxPosX = i+1; maxPosY = j+1; } } else result[i+1][j+1] = 0; System.out.print("maxLength: " + maxLength + " "); System.out.print("maxPos: " + maxPosX + ", " + maxPosY + " "); System.out.println(); for(int i = maxPosX - maxLength; i < maxPosX; i++ ) System.out.print(char1[i]); } public static void main(String[] args) { // TODO Auto-generated method stub char[] char1 = string1.toCharArray(); char[] char2 = string2.toCharArray(); searchlcs(char1, char2); } }
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-07-03 13:47:4614楼 得分:0
    13楼是lcs算法
    craky狂人,你的算法时间复杂度比较高
    最坏的情况下,你需要做m*(m-1)/2次indexof操作
    首先我们不知道indexof实现的具体算法,假设使用的是KMP算法
    那么时间复杂度是O(m+n),所以你的时间复杂度是O(m*m*(m+n))
    如果indexof是一般的方法的话,时间复杂度是O(m*n)
    那么你的时间复杂度是O(m*m*m*n)

    而lcs的时间复杂度只要O(m*n)
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • craky
    • 等级:
    发表于:2008-07-03 13:48:2215楼 得分:10
    [color=#FF00FF]郁闷疯掉,今天这是咋的了,这么简单个问题都搞错,我上面发的全不对,正确的如下[/color]

    Java code
    /** * 比较两个字符串是否含有共同的子字符串 * @param str1 字符串一 * @param str2 字符串二 * @param includeSelf 子字符串是否包括本身 * @return 比较结果 */ public static boolean hasSameSubStr(String str1, String str2, boolean includeSelf) { String shortStr = str1.length() > str2.length()? str2: str1; String longStr = str1.length() > str2.length()? str1: str2; String temp = ""; for(int i = 0; i < shortStr.length(); i++) { for(int j = i + 2; j <= shortStr.length(); j++) { temp = shortStr.substring(i, j); boolean flag1 = includeSelf && longStr.indexOf(temp) >= 0; boolean flag2 = !includeSelf && !temp.equals(shortStr) && longStr.indexOf(temp) >= 0; if(flag1 || flag2) { return true; } } } return false; } /** * 获取两个字符串的最大的子字符串集合 * @param str1 字符串一 * @param str2 字符串二 * @param includeSelf 子字符串是否包括本身 * @return 最大的子字符串集合 */ public static List<String> getMaxSameSubStr(String str1, String str2, boolean includeSelf) { String shortStr = str1.length() > str2.length()? str2: str1; String longStr = str1.length() > str2.length()? str1: str2; String temp = ""; int subLength = 0; List<String> sameSubs = new ArrayList<String>(); for(int i = 0; i < shortStr.length(); i++) { for(int j = i + 2; j <= shortStr.length(); j++) { temp = shortStr.substring(i, j); boolean flag1 = includeSelf && longStr.indexOf(temp) >= 0; boolean flag2 = !includeSelf && !temp.equals(shortStr) && longStr.indexOf(temp) >= 0; if(flag1 || flag2) { if(temp.length() > subLength) { subLength = temp.length(); sameSubs.clear(); sameSubs.add(temp); } else if(temp.length() == subLength) { sameSubs.add(temp); } } } } return sameSubs; } /** * 比较两个字符串是否含有子字符串,如果有,获取最大的子字符串集合 * 返回值为List,长度为2,第一个元素为boolean型,表示是否含有子字符串,第二个元素为List<String>型,表示最大子字符串的集合 * @param str1 字符串一 * @param str2 字符串二 * @param includeSelf 是否包括自身 * @return 比较结果 */ public static List<Object> compareStrWithSub(String str1, String str2, boolean includeSelf) { String shortStr = str1.length() > str2.length()? str2: str1; String longStr = str1.length() > str2.length()? str1: str2; String temp = ""; int subLength = 0; boolean hasSame = false; List<String> sameSubs = new ArrayList<String>(); List<Object> ret = new ArrayList<Object>(); for(int i = 0; i < shortStr.length(); i+