当前位置:编程学习 > JAVA >>

紧急!!!另一个单词对比的问题

--------------------编程问答-------------------- 可以用kmp算法试试

public class kmp{
 public static void main(String[] args)
 {
  String a = "aaabcabcdeadfskdljfa;lskjdf;kljsdkjfeilskjf";
  String b = "abcabcde";
  int c = kmp_find(a,b,0);
  System.out.println(c);
 }
 static int[] GetNext(String fidStr)
 {
  int len = fidStr.length();
  int next[] = new int[len];
  int j = -1, i = 0;
  next[0] = -1;
  while(i < len-1)//这里这个减1是必要的,因为i关系到了要算出next的前一个
  {
   if(-1 == j || fidStr.charAt(j) == fidStr.charAt(i))
   {
    ++i; ++j;
    if(fidStr.charAt(j) == fidStr.charAt(i))
     next[i] = next[j];
    else
     next[i] = j;
   }
   else
   {
    j = next[j];
   }
  }
  return next;
 }
 static int kmp_find(String SurStr, String FidStr, int pos)
 {
  int next[] = GetNext(FidStr);
  int j = 0;
  int i = pos;
  while(j < FidStr.length() && i < SurStr.length()-FidStr.length()+1)
  {
   if(-1 == j || FidStr.charAt(j) == SurStr.charAt(i))
   {
    j++; i++;
   }
   else
   {
    j = next[j]; 
   }
  }
  if(j == FidStr.length())
  {
   return i-FidStr.length();
  }
  else
  {
   return -1;
  }
 }
}


--------------------------------------------------------------------------------


--------------------编程问答-------------------- 我告诉你一个好办法吧
把26个英文字母分别于前26个素数相对应(2,3,5...),这不不难吧
然后每个单词的字母都是素数,一个单词就用这个单词的每个字母所对应的素数乘起来,算出乘积
每个乘积代表一个单词,两个单词比较的时候就选乘积大的那个除以小的那个,
如果得出的结果是那26个素数中的一个,就继续比较,否则就停止比较


这样问题应该就简化了不少 --------------------编程问答-------------------- 题目要求的事要用布尔型,因为我还要插入其他的比较。问题是我不知道怎么实现同一个文本里怎么两两比较 --------------------编程问答-------------------- 感觉楼主你是不是之前发过两个类似的帖子?

下面这个程序,可以按照你的要求比较,而且允许乱序,本质上就是集合减法运算:

public class TextCompare {

    public static void main(String[] args) throws Exception {
        System.out.println(checkOnlyOne("trobato", "troato"));
        System.out.println(checkOnlyOne("troato", "trobato"));
        System.out.println(checkOnlyOne("nnice", "nmice"));
        System.out.println(checkOnlyOne("mice", "nmice"));
        System.out.println(checkOnlyOne("mice", "ecima"));
        System.out.println(checkOnlyOne("mice", "mice"));
    }

    public static boolean checkOnlyOne(String a, String b) {
        int ca = minus(a,b).size();
        int cb = minus(b,a).size();
        return (ca + cb == 1);        
    }
    
    public static List<Character> minus(String base, String minus) {
        List<Character> cb = toChars(base);
        List<Character> cm = toChars(minus);
        List<Character> ret = minus(cb, cm);
        //System.out.println(ret);
        return ret;
    }

    private static List<Character> minus(List<Character> base, List<Character> minus) {
        List<Character> ret = new ArrayList<Character>();
        ret.addAll(base);
        for (Character c : minus) {
            for (int i = 0; i < ret.size(); i++) {
                if (ret.get(i).equals(c)) {
                    ret.remove(i);
                    break;
                }
            }
        }

        return ret;
    }

    private static List<Character> toChars(String str) {
        List<Character> ret = new ArrayList<Character>();
        char[] cs = str.toCharArray();
        for (char c : cs) {
            ret.add(c);
        }
        return ret;
    }
}


结果:
true
true
false
true
true
false --------------------编程问答-------------------- 兄台好思路,不过如果一个单词很长而且尽是xzy之类的话,基本上是不可行的了,会有溢出的。

其实用一个32位的整数来表示一个单词即可,将32位的底26位每一位映射为一个字母,然后可以将每个单词中那些字母对应的位置1,会得出一个32位的整数了,顺下的就是比较整数的技巧了。


引用 2 楼 wangdong20 的回复:
我告诉你一个好办法吧
把26个英文字母分别于前26个素数相对应(2,3,5...),这不不难吧
然后每个单词的字母都是素数,一个单词就用这个单词的每个字母所对应的素数乘起来,算出乘积
每个乘积代表一个单词,两个单词比较的时候就选乘积大的那个除以小的那个,
如果得出的结果是那26个素数中的一个,就继续比较,否则就停止比较


这样问题应该就简化了不少
--------------------编程问答-------------------- 至于lz的两两比较这个问题实在是太简单了,应该自己去查阅一些书籍,然后自己多多思考。 --------------------编程问答--------------------
引用 5 楼 lpp 的回复:
兄台好思路,不过如果一个单词很长而且尽是xzy之类的话,基本上是不可行的了,会有溢出的。

其实用一个32位的整数来表示一个单词即可,将32位的底26位每一位映射为一个字母,然后可以将每个单词中那些字母对应的位置1,会得出一个32位的整数了,顺下的就是比较整数的技巧了。



引用 2 楼 wangdong20 的回复:

我告诉你一个好办法吧
把26个英文字母分别于前26个素数……

可以用BigInteger() --------------------编程问答-------------------- 哦,要不您试试看看,能不能实现。第26位素数本身是很大的哦。

引用 7 楼 wangdong20 的回复:
引用 5 楼 lpp 的回复:
兄台好思路,不过如果一个单词很长而且尽是xzy之类的话,基本上是不可行的了,会有溢出的。

其实用一个32位的整数来表示一个单词即可,将32位的底26位每一位映射为一个字母,然后可以将每个单词中那些字母对应的位置1,会得出一个32位的整数了,顺下的就是比较整数的技巧了。



引用 2 楼 wangdong20 的回复:

我告诉你一个好办法吧
……
--------------------编程问答-------------------- 7楼和8楼的就别吵了,楼主要的内容,字母会重复的,没注意楼主的举例是:trobato?
所以你们的招数都存在一定的问题。 --------------------编程问答-------------------- lz表达的问题本身就不是很清楚:到底是要两两比较还是前后循环比较?
“这样前面那个单词其实是包括后面那个单词的”我只取了这句话来讨论的,lz其他的要求不理解,直接无视了。

另“前后单词相同,但是后面那个单词比前面那个单词多一个字母或者少一个字母”这句话我抓破脑袋也没整明白,求明白人翻译一下。“相同”了为什么还要有“但。。。”?

引用 9 楼 ldh911 的回复:
7楼和8楼的就别吵了,楼主要的内容,字母会重复的,没注意楼主的举例是:trobato?
所以你们的招数都存在一定的问题。
--------------------编程问答--------------------
引用 9 楼 ldh911 的回复:
7楼和8楼的就别吵了,楼主要的内容,字母会重复的,没注意楼主的举例是:trobato?
所以你们的招数都存在一定的问题。

我觉得就算重复也没问题,用素数方法还是可以的,相差只有一个字母而已,而那个字母可以用前26个素数
而且第26个素数也不大也就是101,不信自己写个程序看看第26个素数是几?(从2开始算) --------------------编程问答-------------------- 第26个素数是101,我们取个平均数吧,第13个素数是43,英文单词我们取最常见的长度8,算算得多大。43^8 --------------------编程问答-------------------- 错了!!不是直接输入单词对比,是要读取文本,然后对比,所以不能直接对比单词。要读文本,读单词,然后一个个对比!!! --------------------编程问答-------------------- 解决没 刚看到你的问题,自己做了下 解决了(应该有更好的方案)
附我的思路:先把文件中的内容读入到字符串数组中,然后再循环比较数组中的元素

判断依据:
1.后面和前面字符相同,但后者比前者多一个字符或者少一个字符 就是说前面字符contains后面字符
或者后面字符contains前面字符,前面字符比后面字符长1或者短1

就是我if里面判断的条件

伪代码如下:

String str="";
         try {
BufferedReader bf = new BufferedReader(new FileReader("D:\\1.txt"));
String s ="";

while((s=bf.readLine())!=null){

//;
str+=s+"_";
//
}
bf.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

//System.out.println(str);
String[] strArray=str.split("_");
//System.out.println(strArray.length);
for(int i=0;i<strArray.length;i++){
//System.out.println(strArray[i]);
for(int j=0;j<strArray.length-i;j++){
if((strArray[j].contains(strArray[j+1])||strArray[j+1].contains(strArray[j]))&&(((strArray[j].length()+1)==strArray[j+1].length())
||((strArray[j].length()-1)==strArray[j+1].length()))){
//return true;
System.out.println("true");
}
else{
System.out.println("false");
return;
}
} --------------------编程问答-------------------- 楼主可以把我上面的方法封装一下,因为我直接在main()函数中验证的,最好是把我上面的代码独立出来,供其他
地方调用会看起来整洁些。
补充:Java ,  Java SE
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,