求一个遍历集合的算法

zhongzuo1981 2015-04-16 03:49:42
一个有N个元素的集合,其中有相同元素。
需要得到按重复元素多少排序的新集合。
{"a","b","c","c","a","c"}
得到
{"c","a","b"}
有啥好算法?
...全文
420 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
之诚 2015-04-17
  • 打赏
  • 举报
回复
Set set = new TreeSet(); TreeSet集合不能有重复值,并且里面的数据是排好序的。 TreeSet的底层实现是采用红-黑树的数据结构,采用这种结构可以从Set中获取有序的序列,但是前提条件是:元素必须实现Comparable接口,该接口中只用一个方法,就是compareTo()方法。当往Set中插入一个新的元素的时候,首先会遍历Set中已经存在的元素(当然不是采用顺序遍历,具体采用什么方法,建议自己去看看源码),并调用compareTo()方法,根据返回的结果,决定插入位置。进而也就保证了元素的顺序。
姜小白- 2015-04-17
  • 打赏
  • 举报
回复
给个 javascript 版的

<script>
var arr = ["a", "a", "b", "b", "b", "c", "d", "d", "e", "f", "f", "f", "f"];

var o1 = {},
o2 = {},
_arr = [],
arr_ = [];

for (var i = 0, l = arr.length; i < l; i++) {
var key = arr[i];
o1[key] ? ++o1[key] : o1[key] = 1;
}

console.log(o1);

for (var k in o1) {
var v = o1[k];
if (o2[v]) {
o2[v].push(k)
} else {
o2[v] = [k];
_arr.push(v);
}
}

console.log(o2);

_arr.sort(function(v1, v2) {
return v2 - v1;
});
console.log(_arr);

for (var i = 0, l = _arr.length; i < l; i++) {
arr_.push(o2[_arr[i]].join(","));
}
console.log(arr_.join(","));
</script>
JPF1024 2015-04-17
  • 打赏
  • 举报
回复
gzl=12758 hzld=12736 bowz=12531 flzk=12507 aja=12442 elztr=12406 cor=12335 dpco=12286 10多万个字符,大概不到10S就出来了。


  String [] arrays = new String[100001];
        String [] abc = {"aja","bowz","cor","dpco","elztr","flzk","gzl","hzld","ildsk"};
        for (int i = 0; i < arrays.length; i++) {
            arrays[i]=abc[new Random().nextInt(8)];
        }
        
/*其他跟上面的一样*/

引用 17 楼 zhongzuo1981 的回复:
[quote=引用 13 楼 dcxy0 的回复:] 思考了一晚上,总算没辜负那么多脑细胞。。。 下面的代码请用java8运行!!! 有部分代码是刻意为了简洁书写,你可以格式化之后再看。



/**
 * Created by puruidong on 2015/4/16.
 */
public class TestDemo {
    public static void main(String[] args) {
        String [] arrays = {"a","b","c","c","a","c","dsa","a","d","k","z","r","z","a","bc","r","a","c"};
        /*太懒,直接就list遍历输出吧.*/
        Arrays.asList(showCopyNum(arrays)).forEach((x)->{System.out.println(x);});
        /*
        * 下面是返回回来的数组.
        showCopyNum(arrays);
        */
    }

    private static Object[] showCopyNum(String[] array){
        Set<String> set = new HashSet<>();
        Map<String,Integer> maps = new TreeMap<>();
        for (String str:array)
            maps.put(str,(set.add(str)?1:maps.get(str)+1));
        return maps.entrySet().stream().sorted(new Comparator<Map.Entry<String, Integer>>() {
            @Override
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {return o2.getValue().compareTo(o1.getValue());}}).toArray();
    }
}
运行截图:
看着不错,能给翻译成java6么[/quote]
JPF1024 2015-04-17
  • 打赏
  • 举报
回复
引用 16 楼 zhongzuo1981 的回复:
谢谢楼上各位,只是那个数组里有小10w个字符串元素,不知道楼上给出的哪个性能好。待我试试。
虽然不知道你为啥会有这样的需求,但是十万个估计也需要一定时间,建议用Java8试试
JPF1024 2015-04-17
  • 打赏
  • 举报
回复
引用 17 楼 zhongzuo1981 的回复:
[quote=引用 13 楼 dcxy0 的回复:] 思考了一晚上,总算没辜负那么多脑细胞。。。 下面的代码请用java8运行!!! 有部分代码是刻意为了简洁书写,你可以格式化之后再看。



/**
 * Created by puruidong on 2015/4/16.
 */
public class TestDemo {
    public static void main(String[] args) {
        String [] arrays = {"a","b","c","c","a","c","dsa","a","d","k","z","r","z","a","bc","r","a","c"};
        /*太懒,直接就list遍历输出吧.*/
        Arrays.asList(showCopyNum(arrays)).forEach((x)->{System.out.println(x);});
        /*
        * 下面是返回回来的数组.
        showCopyNum(arrays);
        */
    }

    private static Object[] showCopyNum(String[] array){
        Set<String> set = new HashSet<>();
        Map<String,Integer> maps = new TreeMap<>();
        for (String str:array)
            maps.put(str,(set.add(str)?1:maps.get(str)+1));
        return maps.entrySet().stream().sorted(new Comparator<Map.Entry<String, Integer>>() {
            @Override
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {return o2.getValue().compareTo(o1.getValue());}}).toArray();
    }
}
运行截图:
看着不错,能给翻译成java6么[/quote] 不好意思,不是不想,只是不能。因为很多新方法是java8才有的,所以没法翻译成Java6
zhongzuo1981 2015-04-17
  • 打赏
  • 举报
回复
引用 5 楼 shixitong 的回复:
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class Test8 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		String[] arr={"a","b","c","c","a","c"};
		Map<String,Integer> map = new HashMap<String,Integer>();
		MyValueComparator vc = new MyValueComparator(map);
		Map<String,Integer> map1 = new TreeMap<String,Integer>(vc);
		for(int i=0;i<arr.length;i++){
			String str1=arr[i];
			if(map.containsKey(str1)){
				map.put(str1, map.get(str1).intValue()+1);
			}
			else{
				map.put(str1, 1);
			}
		}
		map1.putAll(map);
		Object[] strArray_new = (Object[])map1.keySet().toArray();
		System.out.println("原来的数组:"+Arrays.toString(arr));
		System.out.println("处理后的数组:"+Arrays.toString(strArray_new));
	}
	
	

}

class MyValueComparator implements Comparator<String> {  
    Map<String, Integer> map;  
    public MyValueComparator(Map<String, Integer> map) {  
        this.map = map;  
    }  
    public int compare(String a, String b) {  
        if (map.get(a) >= map.get(b)) {  
            return -1;  
        } else {  
            return 1;  
        }   
    }  
}  
版主的方法很给力!
zhongzuo1981 2015-04-17
  • 打赏
  • 举报
回复
引用 13 楼 dcxy0 的回复:
思考了一晚上,总算没辜负那么多脑细胞。。。 下面的代码请用java8运行!!! 有部分代码是刻意为了简洁书写,你可以格式化之后再看。



/**
 * Created by puruidong on 2015/4/16.
 */
public class TestDemo {
    public static void main(String[] args) {
        String [] arrays = {"a","b","c","c","a","c","dsa","a","d","k","z","r","z","a","bc","r","a","c"};
        /*太懒,直接就list遍历输出吧.*/
        Arrays.asList(showCopyNum(arrays)).forEach((x)->{System.out.println(x);});
        /*
        * 下面是返回回来的数组.
        showCopyNum(arrays);
        */
    }

    private static Object[] showCopyNum(String[] array){
        Set<String> set = new HashSet<>();
        Map<String,Integer> maps = new TreeMap<>();
        for (String str:array)
            maps.put(str,(set.add(str)?1:maps.get(str)+1));
        return maps.entrySet().stream().sorted(new Comparator<Map.Entry<String, Integer>>() {
            @Override
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {return o2.getValue().compareTo(o1.getValue());}}).toArray();
    }
}
运行截图:
看着不错,能给翻译成java6么
zhongzuo1981 2015-04-17
  • 打赏
  • 举报
回复
谢谢楼上各位,只是那个数组里有小10w个字符串元素,不知道楼上给出的哪个性能好。待我试试。
姜小白- 2015-04-17
  • 打赏
  • 举报
回复
引用 5 楼 shixitong 的回复:
引用 13 楼 dcxy0 的回复:
引用 10 楼 zwbVsAjava 的回复:
引用 7 楼 empty_null 的回复:
Java板块很久没有这么热闹了,好开心啊 哈哈,大家常来啊,把Java块给撑起来啊
JPF1024 2015-04-16
  • 打赏
  • 举报
回复
思考了一晚上,总算没辜负那么多脑细胞。。。

下面的代码请用java8运行!!!

有部分代码是刻意为了简洁书写,你可以格式化之后再看。




/**
* Created by puruidong on 2015/4/16.
*/
public class TestDemo {
public static void main(String[] args) {
String [] arrays = {"a","b","c","c","a","c","dsa","a","d","k","z","r","z","a","bc","r","a","c"};
/*太懒,直接就list遍历输出吧.*/
Arrays.asList(showCopyNum(arrays)).forEach((x)->{System.out.println(x);});
/*
* 下面是返回回来的数组.
showCopyNum(arrays);
*/
}

private static Object[] showCopyNum(String[] array){
Set<String> set = new HashSet<>();
Map<String,Integer> maps = new TreeMap<>();
for (String str:array)
maps.put(str,(set.add(str)?1:maps.get(str)+1));
return maps.entrySet().stream().sorted(new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {return o2.getValue().compareTo(o1.getValue());}}).toArray();
}
}


运行截图:

乐百川 2015-04-16
  • 打赏
  • 举报
回复
引用 11 楼 fanlvlgh 的回复:
可以考虑Set,不可重复key,直接往里扔,
貌似不对呀,他要求是根据出现次数排序,和个数是有关系的
fanlvlgh 2015-04-16
  • 打赏
  • 举报
回复
可以考虑Set,不可重复key,直接往里扔,
zwbVsAjava 2015-04-16
  • 打赏
  • 举报
回复
采用两个map去实现,第一次以数组元素作为key,出现的次数作为value,这样得到的结果是无序的,但数据时整合过的;然后在用一个有序的map(TreeMap),对原来的map进行反序(即,把第一个map中的key作为第二个map的value,把第一个map中的value作为第二个map的key),这样就得到了有序的排列,然后输出values就可以了。 具体代码(核心的代码也就15行不到): public static void sort(List<String> list) { Map<String, Integer> map = new HashMap<String, Integer>(); for (int k = 0; k < list.size(); k++) { if (k == 0) { map.put(list.get(k), 1); continue; } if (map.keySet().contains(list.get(k))) { map.put(list.get(k), (map.get(list.get(k))) + 1); } else { map.put(list.get(k), 1); } } /** * 以上执行完以后,对value-key反序 */ Map<Integer, String> tree = new TreeMap<Integer, String>();// 这个map是有序的 Iterator<String> it = map.keySet().iterator(); while (it.hasNext()) { String key = it.next(); tree.put(map.get(key), key); } System.out.println("------" + tree.values()); }
tony4geek 2015-04-16
  • 打赏
  • 举报
回复
String[] array = { "a", "b", "c", "c", "a", "c" };

		Collections.sort(Arrays.asList(array));
		System.out.println(Arrays.asList(array).toString());
[a, a, b, c, c, c] 先拍好序再处理。
姜小白- 2015-04-16
  • 打赏
  • 举报
回复
Iterator<Map.Entry<String, Integer>> meIt = map.entrySet().iterator();
while (meIt.hasNext()) {
list.add(meIt.next());
}
修改为
list.addAll(map.entrySet());
empty_null 2015-04-16
  • 打赏
  • 举报
回复
1.subsring和split取出元素放到 数组中 2.排序一下,如果怕comparable麻烦,我给个快排的 void quicksort(String[] a,int l,int r){ if(l<r){ int m=part(a,l,r); quicksort(a,l,m-1); quicksort(a,m+1,r); } } int part(String[] a,int l,int r){ //swap(a,r,random(l,r)); int i=l-1; String key=a[r]; for(int j=l;j<r;j++){ if(a[j]<=key){ ++i; swap(a,i,j); } } swap(a,r,i+1); return i+1; } void swap(String[] a,int l,int r){ String t=a[l]; a[l]=a[r]; a[r]=t; } 3.合并相同项 List<String> list1; List<Integer> list2; int t=1;//代表当前相同个数 for(int i=1;i<len;i++){ if(a[i]==a[i-1]) t++; else{ list1.add(a[i-1]) list2.add(t); t=1; } } 4.再次排序,用上面快排改一下,swap Integer的同时swap掉String保持下标对应 推荐把属性封装成model然后实现comparable接口,毕竟你在用面向对象的语言 5.排序的结果循环一遍
姜小白- 2015-04-16
  • 打赏
  • 举报
回复
实现了功能,但是不够精炼

String[] strArr = {"a","b","c","c","a","c"};
Map<String, Integer> map = new HashMap<String, Integer>();

for (String str : strArr) {
Integer count = map.get(str);
if (null != count) {
map.put(str, count + 1);
} else {
map.put(str, 1);
}
}


List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>();

Iterator<Map.Entry<String, Integer>> meIt = map.entrySet().iterator();
while (meIt.hasNext()) {
list.add(meIt.next());
}

Collections.sort(list, new Comparator<Entry<String, Integer>>(){
public int compare(Entry<String, Integer> arg0, Entry<String, Integer> arg1) {
return arg1.getValue().compareTo(arg0.getValue());
}
});

for (Entry<String, Integer> entry : list) {
System.out.println(entry.getKey());
}
shixitong 2015-04-16
  • 打赏
  • 举报
回复
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class Test8 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		String[] arr={"a","b","c","c","a","c"};
		Map<String,Integer> map = new HashMap<String,Integer>();
		MyValueComparator vc = new MyValueComparator(map);
		Map<String,Integer> map1 = new TreeMap<String,Integer>(vc);
		for(int i=0;i<arr.length;i++){
			String str1=arr[i];
			if(map.containsKey(str1)){
				map.put(str1, map.get(str1).intValue()+1);
			}
			else{
				map.put(str1, 1);
			}
		}
		map1.putAll(map);
		Object[] strArray_new = (Object[])map1.keySet().toArray();
		System.out.println("原来的数组:"+Arrays.toString(arr));
		System.out.println("处理后的数组:"+Arrays.toString(strArray_new));
	}
	
	

}

class MyValueComparator implements Comparator<String> {  
    Map<String, Integer> map;  
    public MyValueComparator(Map<String, Integer> map) {  
        this.map = map;  
    }  
    public int compare(String a, String b) {  
        if (map.get(a) >= map.get(b)) {  
            return -1;  
        } else {  
            return 1;  
        }   
    }  
}  
zhongzuo1981 2015-04-16
  • 打赏
  • 举报
回复
引用 3 楼 snakec0047 的回复:
用frequency查出出现的次数,frequency做键元素做值放进map里,然后根据frequency的大小进行排序 小弟拙见,抛砖引玉
int freq = Collections.frequency(arrlist, "c"); frequency 需要知道集合里有哪些元素,但实际情况不知道。
snakec0047 2015-04-16
  • 打赏
  • 举报
回复
用frequency查出出现的次数,frequency做键元素做值放进map里,然后根据frequency的大小进行排序 小弟拙见,抛砖引玉
加载更多回复(2)

62,616

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧