论坛首页 综合技术论坛

给大家出道题,算法的

浏览 32405 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (17)
作者 正文
   发表时间:2012-02-09   最后修改:2012-02-09
1.先安字符串长度分组。。length为key,StringList为value .
2.遍历每个分组。每个字符串拆分成字符数组重新排序后再合并成字符串,保存一个新字符串组。
3.将重组后字符串作为key,原串作为value,put入map,put之前先get,有相同的则保存为同一组。
觉得还是可行的。。请指点。。。。

重新改造一下:
每个字符串拆分成字符数组重新排序后再合并成字符串

public static void print(){
	String [] ss = new String[]{"hat", "top", "potter", "pot", "pier", "ripe"};
	String [] newss = new String[ss.length];  //保排序后的新字符串数组
	Map<String , List<String>> res = new HashMap<String,List<String>>(); 
	for(int i = 0 ; i < ss.length ; i ++){
		char[] cs = ss[i].toCharArray();
		Arrays.sort(cs);
		newss[i] = new String(cs) ;
		List<String> isE = res.get(newss[i]);
		if(isE == null || isE.size() <= 0 ){ //不存在同样的记录
			isE = new ArrayList<String>();
		}
                isE.add(ss[i]);
	        res.put(newss[i], isE);
	}
	Set<String> keySet = res.keySet();
	for(String s : keySet){
		List<String> print = res.get(s);
		StringBuilder sb = new StringBuilder(s+":");
		for(String sprint : print){
			sb.append(sprint).append(",");
		}
		System.out.println(sb.toString());
	}
}

结果为:
eoprtt:potter,
aht:hat,
opt:top,pot,
eipr:pier,ripe,
0 请登录后投票
   发表时间:2012-02-09   最后修改:2012-02-09
您这个应该就是桶排序吧,不错~

kidding87 写道
jdk用的是归并排序,这里有些不合适,效率不高
改用先统计每个字母的数量再组装字符串,效率提高一倍

public static String sort(String s){
//26个字母
short[] t =new short[26];
char c[]=s.toCharArray();
for(short i=0;i<c.length;t[c[i++]-'a']++) ;
for(short i=0,j=0;i<26&&j<c.length;i++){
for(short k=1;k<=t[i];k++){
c[j++]=(char)(i+'a');
}
}
return new String(c);
}
[\code]
下面有就有个问题了,对于程序来说,字符串是什么,还不是char[],这里我们再思考下,反正都是要比较的,我直接把上面的那个short []t丢出来比较是不是更快

public class Comparable {
public short[] t;
public Comparable(String s){
t=PP.sort2(s);
}
@Override
public boolean equals(Object paramObject) {
if(paramObject==null) return false;
if(paramObject instanceof Comparable){
Comparable cast = (Comparable)paramObject;
if(cast.t.length!=this.t.length) return false;
for(int i=0;i<cast.t.length;i++){
if(cast.t[i]!=this.t[i]) return false;
}
return true;
}
return false;
}
@Override
public int hashCode() {
int r=0;
for(int i=0;i<t.length;i++){
r+=r*31+t[i];
}
return r;
}

}
[\code]

完整测试代码

public class PP {
public static void main(String[] args) {
String s="cccabcfdjfdisojfiosfuqjofjidosjfasofusafus";
double time = System.currentTimeMillis();
for(int i=0;i++<1000000;Arrays.sort(s.toCharArray()));
double time2 = System.currentTimeMillis();
System.out.println((time2-time));
for(int i=0;i++<1000000;sort(s));
double time3 = System.currentTimeMillis();
System.out.println(time3-time2);
for(int i=0;i++<1000000;sort2(s));
double time4 = System.currentTimeMillis();
System.out.println(time4-time3);
String str=new String(s);
double time5 = System.currentTimeMillis();
for(int i=0;i++<1000000;s.equals(str));
double time6 =System.currentTimeMillis();
System.out.println(time6-time5);
Comparable c1= new Comparable(s);
Comparable c2 =new Comparable(s);
double time7 = System.currentTimeMillis();
for(int i=0;i++<1000000;c1.equals(c2));
double time8= System.currentTimeMillis();
System.out.println(time8-time7);
}

public static String sort(String s){
//26个字母
short[] t =new short[26];
char c[]=s.toCharArray();
for(short i=0;i<c.length;t[c[i++]-'a']++) ;
for(short i=0,j=0;i<26&&j<c.length;i++){
for(short k=1;k<=t[i];k++){
c[j++]=(char)(i+'a');
}
}
return new String(c);
}
public static short[] sort2(String s){
//26个字母
short[] t =new short[26];
char c[]=s.toCharArray();
for(short i=0;i<c.length;t[c[i++]-'a']++) ;
return t;
}
}
class Comparable {
public short[] t;
public Comparable(String s){
t=PP.sort2(s);
}
@Override
public boolean equals(Object paramObject) {
if(paramObject==null) return false;
if(paramObject instanceof Comparable){
Comparable cast = (Comparable)paramObject;
if(cast.t.length!=this.t.length) return false;
for(int i=0;i<cast.t.length;i++){
if(cast.t[i]!=this.t[i]) return false;
}
return true;
}
return false;
}
@Override
public int hashCode() {
int r=0;
for(int i=0;i<t.length;i++){
r+=r*31+t[i];
}
return r;
}
}
[\code]

结果
1827.0
968.0
410.0
225.0
142.0
(1827+225)/(410+142)≈3.7
差不多比自己写的耗时多3.7倍

不知道大家能不能理解,利用质数方法是不错,但是字符串长度过大的话,BigInteger的性能太差,它内部其实还是数组,依次遍历相乘再进位的算法,很慢



0 请登录后投票
   发表时间:2012-02-09  
bylijinnan 写道
您这个应该就是桶排序吧,不错~


哈哈,我还不知道什么是桶排序
这个算法的时间复杂度是O(n)左右;归并是log(n);而他们提出的质数算法,查找效率 就是O(1)
,我也牺牲了空间来做键值
不过质数算法的对于大的字符串,空间上不比我这个少,计算键值,键值比对这个性能急剧下降
关键点其实并不只是排序;
而是将排序后的字符串转义,这样的比较速度效率很高
0 请登录后投票
   发表时间:2012-02-09  
将字符串转成字节数组做,排序是按照字节数组的第一个由小到大排序,找出相同的字符串是按照字节数组相加的总和去比较。
0 请登录后投票
   发表时间:2012-02-09   最后修改:2012-02-09
先对每个单词内部按顺序排序,
比如:
hat -> aht
top -> opt
pot -> opt
potter -> eoprtt
pier -> eipr
ripe -> eipr

然后再按排序好的分组,如何?
1 请登录后投票
   发表时间:2012-02-13  
给个erlang写的算法,大家评价下

-module(ksort).
-vsn(1.0).
-author({"jian fan,TianZe Information Inc."}).
-purpose("example of ksort").
-export[(getlist/1)].
-export[(qsort/1)].
-export[(xsort/2)].
%sort the string in list
qsort([]) -> [];
qsort([H|T]) -> [lists:sort(H)]++
                qsort(T).

%get the list 1
getlist([]) -> [];
getlist([H|T]) ->
                [X|L] = D = lists:usort(qsort([H|T])),io:format("getlist1~p~n",[D]),
                getlist([H|T],[X|L]).

%get the list 2
getlist([H|T],[]) -> [];
getlist([H|T],[X|L]) -> D=xsort([H|T],X),io:format("getlist2~p ",[D]),
                        getlist([H|T],L).

%get the string list which sort string is equal with some string.
xsort([],String) -> [];
xsort([X|L],String) -> D=qsort([X]),
                   if D == [String] ->
                    io:format("xsort~p~n",[X]),[X];
                   true ->
                    ""
                   end++
                  xsort(L,String).

ksort:getlist(["hat","top","potter","pot","pier","ripe"].
0 请登录后投票
   发表时间:2012-02-13  
做个map, key是这个单词, value是这个单词按照字母顺序排序后的新词。 然后比较这个map中value一样的归位一组。
0 请登录后投票
   发表时间:2012-02-14   最后修改:2012-02-14
groovy 代码

def input = "hat, top, potter, pot, pier, ripe"
def out = [:]
input.split(", ").each {

 def a = it.toCharArray()
 Arrays.sort(a)
 def key = new String(a)
 
 if(out.containsKey(key)) {
     out.put(key, out.get(key) + ", " + it)
 } else {
     out.put(key, it)
 }
 
}

out.values().each { println it }
0 请登录后投票
   发表时间:2012-02-15  
我的想法是这样的:a,b,c,...z 用1,2,4, ....2的(z-a)次方来表示.
比较两个字符串是否一样:
1. 长度一样
2. 全部字符替换成数字后累加和一样, eg: sum(ab)=1+2=3,sum(ba)=2+1=3

key = length(str)+"-"+sum(str)

key一样,字符就相等.

数据结构实现 Map<String,List>
List放相同单词

代码:

package com.robin.question;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class Question1 {
     
    public static Map<String,Long> letterValueMap = new HashMap();
    Question1(){
        int begin = (int)'a';
        int end = (int)'z';
        for(int i=begin;i<=end;i++){
            String str = String.valueOf((char)i);
            int j = i-begin;
            Long value = _MN(2,j);
            letterValueMap.put(str, value);
        }
    }
   
    public  void PrintGroupsWithSameLetters (String str){
        Map ret = new TreeMap<String,ArrayList>();
        if(str!=null && str.length()>0){
            String arr [] = str.split(",");
            for(int i=0;i<arr.length;i++){
                String s = arr[i];
                Long value = calStr(s);
                StringBuffer key = new StringBuffer("");
                key.append(s.length());
                key.append("-");
                key.append(value);
                if(ret.containsKey(key.toString())){
                    List strList = (List) ret.get(key.toString());
                    strList.add(s);
                }else{
                    List strList = new ArrayList();
                    strList.add(s);
                    ret.put(key.toString(), strList);
                }
            }
        }
       
        output(ret);
    }
   
    public static void output(Map ret){
        if(ret!=null && !ret.isEmpty()){
            Set<String> keys = ret.keySet();
            for(String key:keys){
              List<String> list = (List) ret.get(key);
             if(list!=null && !list.isEmpty()){
                  for(int i=0;i<list.size();i++){
                      if(i>0){
                          System.out.print(",");
                      }
                      System.out.print(list.get(i).trim());
                  }
                 
                  System.out.println();
              }
            }
        }
    }
  
   
    public static Long _MN(int m,int n){
        Long value = 1L;
        while(n>0){
            value = value * m;
            n--;
        }
       
        return value;
    }
   
    public static Long calStr(String str){
        Long value = 0l;
        str = str.toLowerCase().trim();
        char strArr[] = str.toCharArray();
        for(int i=0;i<strArr.length;i++){
            String s = String.valueOf(strArr[i]);
            value = value +letterValueMap.get(s);
        }
       
        return value;
    }
   
    public static void main(String[] args) {
        Question1 a = new Question1();
        String str = "hat, top, potter, pot, pier, ripe";
        a.PrintGroupsWithSameLetters(str);
    }

}
0 请登录后投票
   发表时间:2012-02-15  
qseasideq 写道
我的想法是这样的:a,b,c,...z 用1,2,4, ....2的(z-a)次方来表示.
比较两个字符串是否一样:
1. 长度一样
2. 全部字符替换成数字后累加和一样, eg: sum(ab)=1+2=3,sum(ba)=2+1=3

key = length(str)+"-"+sum(str)

key一样,字符就相等.

数据结构实现 Map<String,List>
List放相同单词

代码:

package com.robin.question;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class Question1 {
     
    public static Map<String,Long> letterValueMap = new HashMap();
    Question1(){
        int begin = (int)'a';
        int end = (int)'z';
        for(int i=begin;i<=end;i++){
            String str = String.valueOf((char)i);
            int j = i-begin;
            Long value = _MN(2,j);
            letterValueMap.put(str, value);
        }
    }
   
    public  void PrintGroupsWithSameLetters (String str){
        Map ret = new TreeMap<String,ArrayList>();
        if(str!=null && str.length()>0){
            String arr [] = str.split(",");
            for(int i=0;i<arr.length;i++){
                String s = arr[i];
                Long value = calStr(s);
                StringBuffer key = new StringBuffer("");
                key.append(s.length());
                key.append("-");
                key.append(value);
                if(ret.containsKey(key.toString())){
                    List strList = (List) ret.get(key.toString());
                    strList.add(s);
                }else{
                    List strList = new ArrayList();
                    strList.add(s);
                    ret.put(key.toString(), strList);
                }
            }
        }
       
        output(ret);
    }
   
    public static void output(Map ret){
        if(ret!=null && !ret.isEmpty()){
            Set<String> keys = ret.keySet();
            for(String key:keys){
              List<String> list = (List) ret.get(key);
             if(list!=null && !list.isEmpty()){
                  for(int i=0;i<list.size();i++){
                      if(i>0){
                          System.out.print(",");
                      }
                      System.out.print(list.get(i).trim());
                  }
                 
                  System.out.println();
              }
            }
        }
    }
  
   
    public static Long _MN(int m,int n){
        Long value = 1L;
        while(n>0){
            value = value * m;
            n--;
        }
       
        return value;
    }
   
    public static Long calStr(String str){
        Long value = 0l;
        str = str.toLowerCase().trim();
        char strArr[] = str.toCharArray();
        for(int i=0;i<strArr.length;i++){
            String s = String.valueOf(strArr[i]);
            value = value +letterValueMap.get(s);
        }
       
        return value;
    }
   
    public static void main(String[] args) {
        Question1 a = new Question1();
        String str = "hat, top, potter, pot, pier, ripe";
        a.PrintGroupsWithSameLetters(str);
    }

}


不知道楼上验算过这个公式么
∑j2^k≠∑j'2^k'
∑j≠∑j'


0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics