JAVA怎么计算txt中一个1亿个浮点数的中位数?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA怎么计算txt中一个1亿个浮点数的中位数?相关的知识,希望对你有一定的参考价值。

你这个应该是面试题吧,平时不会让你做这样的问题
首先要了解一下什么是中位数,中位数就是数列中间的那个数,
如果一个集合是奇数个,那么中位数就是按大小排列后,最中间那个数,
如果一个集合是偶数个,那么中位数就是按大小排列后,最中间那2个数的平均数
那计算一个1亿个浮点数的中位数,说白了是要你排序,然后找到中间那两个数字的平均数
剩下就是排序的算法部分了,无规律的随机数字可以考虑快排算法

补充代码(快排)
那就用快排好了
package quickSort;
public class QuickSort
private static int count;
/**
* 测试
* @param args
*/
public static void main(String[] args)
int[] num = 3,45,78,64,52,11,64,55,99,11,18;
System.out.println(arrayToString(num,"未排序"));
QuickSort(num,0,num.length-1);
System.out.println(arrayToString(num,"排序"));
System.out.println("数组个数:"+num.length);
System.out.println("循环次数:"+count);


/**
* 快速排序
* @param num 排序的数组
* @param left 数组的前针
* @param right 数组后针
*/
private static void QuickSort(int[] num, int left, int right)
//如果left等于right,即数组只有一个元素,直接返回
if(left>=right)
return;

//设置最左边的元素为基准值
int key=num[left];
//数组中比key小的放在左边,比key大的放在右边,key值下标为i
int i=left;
int j=right;
while(i<j)
//j向左移,直到遇到比key小的值
while(num[j]>=key && i<j)
j--;

//i向右移,直到遇到比key大的值
while(num[i]<=key && i<j)
i++;

//i和j指向的元素交换
if(i<j)
int temp=num[i];
num[i]=num[j];
num[j]=temp;


num[left]=num[i];
num[i]=key;
count++;
QuickSort(num,left,i-1);
QuickSort(num,i+1,right);

private static String arrayToString(int[] arr,String flag)
String str = "数组为("+flag+"):";
for(int a : arr)
str += a + "\t";
return str;追问

主要是排序怎么排呢,直接排内存会溢出

参考技术A 无非就是两个思想,一个是分段,因为数据太多,可以一次处理
那么就需要分成几段,对每段进行排序
其次是归并排序,两两归并,就能将各个分段合成一个整体

使用 SSE 将 4 个浮点数乘以 4 个浮点数的最有效方法是啥?

【中文标题】使用 SSE 将 4 个浮点数乘以 4 个浮点数的最有效方法是啥?【英文标题】:What's the most efficient way to multiply 4 floats by 4 floats using SSE?使用 SSE 将 4 个浮点数乘以 4 个浮点数的最有效方法是什么? 【发布时间】:2009-08-04 12:34:17 【问题描述】:

我目前有以下代码:

float a[4] =  10, 20, 30, 40 ;
float b[4] =  0.1, 0.1, 0.1, 0.1 ;
asm volatile("movups (%0), %%xmm0\n\t"
             "mulps (%1), %%xmm0\n\t"             
             "movups %%xmm0, (%1)"             
             :: "r" (a), "r" (b));

首先我有几个问题:

(1) 如果我要在 16 字节边界上对齐数组,它甚至可以工作吗?由于数组是在堆栈上分配的,对齐它们是真的几乎不可能吗?

查看此帖子的选定答案:Are stack variables aligned by the GCC __attribute__((aligned(x)))?

(2) 可以重构代码以提高效率吗?如果我将两个浮点数组都放入寄存器而不是一个呢?

谢谢

【问题讨论】:

【参考方案1】:

用C写,用

gcc -S -mssse3

如果你有一个相当新的 gcc 版本。

【讨论】:

哪些 C 代码可以编译成这些 sse 指令?你有例子吗? float a[4] = 10, 20, 30, 40 ;浮动 b[4] = 0.1, 0.1, 0.1, 0.1 ; int foo(void) int i;对于 (i=0; i 【参考方案2】:

如果我要在 16 字节边界上对齐数组,它甚至可以工作吗?由于数组是在堆栈上分配的,对齐它们是真的几乎不可能吗?

要求堆栈上的对齐有效。否则内在函数将不起作用。我猜你引用的帖子与他为对齐值选择的过高值有关。

到2:

不,性能不应该有差异。多个处理器的指令时序见site。


堆栈变量的对齐方式是如何工作的:

push    ebp
mov ebp, esp
and esp, -16                ; fffffff0H
sub esp, 200                ; 000000c8H

and 将堆栈的开头对齐到 16 字节。

【讨论】:

【参考方案3】:

(1) 如果我要在 16 字节边界上对齐数组,它甚至可以工作吗?由于数组是在堆栈上分配的,对齐它们是真的几乎不可能吗?

不,使用and对齐堆栈指针非常简单:

and esp, 0xFFFFFFF0 ; aligned on a 16-byte boundary

但您应该使用 GCC 提供的内容,例如 16 字节类型,或 __attribute__ 来自定义对齐方式。

【讨论】:

感谢您的回答,您能否向我解释一下如何使用“和”进行对齐?我不太“明白”它:) 回想一下 some_bit and 0 = 0a/16 = a&gt;&gt;4 如果 a 未签名。像这样使用and 会将四个最低有效位设置为零,而其他位保持不变。实际上,如果将esp 除以 16 会发生什么?它被右移 4,四个“丢失”的位是余数。因此这四位应该是 0,所以esp 可以被 16 整除。真正发生的是它减去最多 15,所以esp % 16 == 0。(减去esp 表示在堆栈上分配更多空间)。【参考方案4】:

GCC 是否支持__m128 数据类型?如果是这样,那是保证 16 字节对齐数据类型的最佳计划。尽管如此,还是有__attribute__((aligned(16))) 用于对齐事物。如下定义你的数组

float a[4] __attribute__((aligned(16))) =  10, 20, 30, 40 ;
float b[4] __attribute__((aligned(16))) =  0.1, 0.1, 0.1, 0.1 ;

然后改用 movaps :)

【讨论】:

谢谢;但正如本文***.com/questions/841433/… 中所述,似乎不可能对齐分配在堆栈上的数组? (与 .data 中分配的全局数组相反) 感谢 Bastien 的修复 :) Banister ...你可以试试看会发生什么吗?如果与解释相关联的内容是正确的,那么就不可能正确对齐 double 之类的东西,但它们确实会对齐。 是的,我很快就会...我感觉链接的解释是错误的,因为这个问题中的每个人似乎都暗示。谢谢大家! :)【参考方案5】:

使用内在函数要快得多,尤其是在优化时。 我编写了简单的测试并比较了两个版本(asm 和内在)

unsigned long long time1;
__m128 a1,b1;


a1=_mm_set_ps(10, 20,30,40);
b1=_mm_set_ps(0.1, 0.1, 0.1, 0.1);
float a[4] =  10, 20, 30, 40 ;
float b[4] =  0.1, 0.1, 0.1, 0.1 ;

time1=__rdtsc();
a1=_mm_mul_ps(a1,b1);
time1=__rdtsc() - time1 ;
printf("Time: %llu\n",time1);


time1=__rdtsc();
asm volatile("movups (%0), %%xmm0\n\t"
                 "mulps (%1), %%xmm0\n\t"
                 "movups %%xmm0, (%1)"
                 :: "r" (a), "r" (b));
time1=__rdtsc() - time1 ;
printf("Time: %llu\n",time1);

内部版本 50-60 处理器时间戳 Asm 版本 ~1000 过程时间戳

你可以在你的机器上测试它

【讨论】:

【参考方案6】:

关于重构。你可以使用内在的。 示例:

#include <emmintrin.h>

int main(void)

    __m128 a1,b1;

    a1=_mm_set_ps(10, 20,30,40);
    b1=_mm_set_ps(0.1, 0.1, 0.1, 0.1);

    a1=_mm_mul_ps(a1,b1);

    return 0;

使用优化 gcc (-O2, -O3) 它可能会比 asm 更快。

【讨论】:

你认为它会运行多快?你能做基准测试吗? 看下一篇,我正在测试它

以上是关于JAVA怎么计算txt中一个1亿个浮点数的中位数?的主要内容,如果未能解决你的问题,请参考以下文章

2个浮点数进行计算

找工作——大数据的处理方式

点后 3 位浮点数

java输入3个浮点数,求它们的乘积

如何将 map.getBounds() 作为 4 个浮点数的列表?

java2亿个随机生成的无序整数,如何找到其中位数