我用了一个很笨的方法实现了要求,各位高手帮我看看怎么改进效率才能更好呢
其实最关键的问题就是按value值排序之后怎么能对应上它在hashmap中的key。
要求用Hashmap的
//读取一行字符串,判定各个字符出现的次数。并按出现次数由大到小排序。
import java.util.*;
import java.io.*;
public class Testdebug {
public static void main(String[] args) throws Exception{
System.out.println("请输入:");
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String s;
s=br.readLine();
char[] str=new char[s.length()];
str=s.toCharArray();
Vector v=new Vector(); //定义vector是为了使用Collections.frequency
for(int i=0;i<s.length();i++){  //将输入的字符存入vector
v.add(str[i]);
}
HashMap map=new HashMap();
Iterator i=v.iterator();
while(i.hasNext())
{
Character ch=(Character)i.next();
int f=Collections.frequency(v, ch);
map.put(ch,f);
}
int[] val=new int[s.length()]; //
char[] k=new char[s.length()]; //
int n=0; //
Set set=map.keySet();
Iterator m=set.iterator();
while(m.hasNext())
{
Object key=m.next();
k[n]=(Character)key;   //把key值存入字符数组k
Object value=map.get(key);
val[n]=(Integer)value; //把value值存入整数组val
System.out.println(" "+key+"="+value);
n++;
}
char temp1;
int temp2;
for(int p=0;p<=n-2;p++){  //冒泡排序
for(int q=0;q<=n-1-p;q++){                       
if(val[q]<val[q+1]){
temp2=val[q];temp1=k[q];
val[q]=val[q+1];k[q]=k[q+1];
val[q+1]=temp2;k[q+1]=temp1;
}
}
}
for(int x=0;x<n;x++){
System.out.println(k[x]+"="+val[x]);
}
}
}

解决方案 »

  1.   

    如果值对键不是一一映射 那就将排好序的键值对(map)存入比如List
      

  2.   

    记得有个entrySet,每个entrySet对应着一个key 和一个value,你看看试着对entrySet按value来排序
      

  3.   

    我个人觉得没有必要对hashmap中的value排序,排序并不会使查找变快
    map中的hash函数好像和元素的位置没有多大关系
      

  4.   

    将map的key和value身份颠倒一下
    对颠倒后的key(即原来的value)排序 要找原来的key直接通过get方法
    对于相同的value 可另行对key做添加标记处理
      

  5.   

    你的目的就是输入一个字符串,然后计算字符串中每个字符出现的顺序,然后按照出现次数多少给排序吧。
    一会儿给你个算法,没有必要用Map这种数据结构,因为Map里的Value不值得去排序。
      

  6.   

    其实这样的话就可能出问题了,就比如万一有个相同值的value怎么办?这不是丢失了一对映射吗?
      

  7.   

    看了一下,效率上如果要提高,也就只能在排序算法上了,比如用快排或者插入排序,比冒泡快。如果需要用Map,排序的事是可以交给TreeSet做的。
      

  8.   

    我觉得可以不用Map, 就用一个int数组好了(如果不够, 就用long), 该数组长度为65536个, 对应unicode字符.
    这个int数组高16位放char的值,后16位放频率值
    1)初始化char的值, 对int数组中依高16为的赋值为0到65536
    for (int i = 0; i < 65536; i++)
    {
      a[i] = (i << 16  & 0xffff);
    }
    2)得到输入字符串,计算字符频率
    for (int i = 0; i < inputstr.length; i++)
    {
      a[inputstr.charAt[i]] += 1;
    }
    3)对数组按照后16位进行排序 (具体算法看你选择了)
      

  9.   

    什么算法?我一开始用字符数组做的,计算频率很好做,但是再排序就没办法了。java才学10天,也是第一次接触面对对象语言,不懂的地方很多,以后要多多向LS各位学习。
      

  10.   

    我靠,anqini你是叫霍俊嘛?你和我这个同学长的好像啊...
      

  11.   

    这个有这么麻烦?lz能确定每个字符出现的次数,想对次数做排序,那就这样咯,计算出的字符出现的次数,添加到一个list中,然后自定义个类实现Comparator接口,用来做排序,再利用Collections.sort(list,new 自定义类名());这样就可以了
    比如:
    package test1;import java.util.*;
    public class csdntest1{
    public static void main(String[] args){
    List list = new ArrayList();
    list.add("3");
    list.add("4");
    list.add("2");
    list.add("5");
    list.add("4");

    Collections.sort(list,new Comparatorsort());
    for(int i = 0;i < list.size();i++){
    System.out.println(list.get(i));
    }
    }
    } class Comparatorsort implements Comparator{
      public int compare(Object o1,Object o2)
         {
             String str1=(String)o1;
             String str2=(String)o2;
             if(str1.compareTo(str2)>0) 
               return -1;
             if(str1.compareTo(str2)<0) 
               return 1;
             return 0;
         }
    }
    只不过是次数要由int转换为String,反正也是个排序,这点应该没有关系.
      

  12.   

    也是
    不过可以间接的通过list来排序:
    LinkedList list=new LinkedList();
    list.addAll(map.values());
    java.util.Collections.sort(list);
      

  13.   


    其实面向对象就是要设计对象。可以把<Character, int>设计成一个对象,然后实现Comparator接口。排序通过TreeSet来排。这个是编程上简单的做法。
    如果你需要算法上快速,其实HashMap、TreeSet、String.toCharAtrray都会有性能消耗,这些操作的复杂度不能单独看成1。所以还是用基本排序的算法排序可能更加可以控制复杂度。
      

  14.   

    将map的key和value身份颠倒一下 
    对颠倒后的key(即原来的value)排序 要找原来的key直接通过get方法 
    对于相同的value 可另行对key做添加标记处理
    [/Quote]
    如何颠倒  value可以重复,但key不允许重复你怎么颠倒啊
      

  15.   


    我一开始也是这么做的,但是问题是 value排序出来了,怎么找到它对应的key值呢?
      

  16.   

    hashmap查找本身就比list或者数组快!
    就像点名,只要人在,你喊名字,马上就有人喊“到”。
      

  17.   

    就采用一楼的方法就可,你这样做纯粹是绕圈,把字符作为主键,数目作为value,有一个,遍历出一个就修改一次数目。然后再排序。
      

  18.   

    调用TreeMap把key和value交换会有个问题,就是key不能重复,有些数据会丢失的。