求java程序:输入n个正整数,分成两组求和,求两列数字组合使这两组的和最接近平均数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求java程序:输入n个正整数,分成两组求和,求两列数字组合使这两组的和最接近平均数相关的知识,希望对你有一定的参考价值。

实用价值:商场打折。。。如:满500返500
注意:每组的数字个数不确定(如输入10个数,可能会产出2个数的和跟其他8个数的和最接近)

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
/**
 * 自己想了个算法,不一定正确
 * 算法过程,将一组数字从小到大排序,然后求这组数字的和/2,用这个求出的值去减去最大数,
 * 如果结果>=0,则放入第一组数字,然后用减的结果继续减第二大数,如果<0则去减第三个数,以此类推
 * 直到每个数都检查一遍
 * 这样第一组数字中的所有数相加能保证<=平均数,并且能最大范围内的接近平均数,
 * 同时没有加入第一组集合的数就是第二组的数字了.
 *
 */
public class NumberGroup 
 public static void main(String[] args) 
  Scanner scan = new Scanner(System.in);
  List<Double> arr = new ArrayList<Double>();
  System.out.println("请输入一组数字:按q停止输入:");
  String s = "";
  while(true)
   s = scan.next();
   if("q".equals(s)) break;
   try
    Double.parseDouble(s);
   catch(Exception ex)
    System.out.println("请输入正确的数字!");
    continue;
   
   arr.add(Double.parseDouble(s));
   System.out.println(String.format("你当前输入了%s,当前的数字集合为:%s", s,Arrays.toString(arr.toArray())));
   
  
  
  
  List<Double> l1 = new ArrayList();// 接收第一组数据
  List<Double> l2 = new ArrayList();// 接收第二组数据
  sort(arr.toArray());// 先排序
  final double average = middle(arr.toArray());// 求中间值
  int i = arr.size()-1;
  double temp=average;
  l1 = subtractor(arr.toArray(),temp,i);
  
  
  for(int j = 0;j<arr.size();j++)
   if(!l1.contains(arr.get(j)))
   l2.add(arr.get(j));
  
  System.out.println("平均数为:"+average);
  System.out.println(Arrays.toString(l1.toArray())+",总和为:"+sum(l1.toArray(),0));
  System.out.println(Arrays.toString(l2.toArray())+",总和为:"+sum(l2.toArray(),0));
 
 /**
  * 先按照顺序从小到大排序
  * 
  * @param arr
  * @return
  */
 public static Object[] sort(Object[] arr) 
  Arrays.sort(arr);
  return arr;
 
 /**
  * 求中间值
  * 
  * @param arr
  * @return
  */
 public static double middle(Object[] arr) 
  return sum(arr,0) / 2;
 
 
 public static double sum(Object[] arr,int i)
  if(i == arr.length) return 0;
  return (double)arr[i]+sum(arr,++i);
 
 
 /**
  * 用平均数依次减去数组中的最大数,如果结果>0,则加入第一组数据,如果小于0,则减去第二大数,依次类推,直到所有数都检查完为止
  * @param arr
  * @param temp
  * @param i
  * @return
  */
 public static List subtractor(Object[] arr,double temp,int i)
  List l = new ArrayList();
  if(i==-1) return l;
  if(temp - Double.parseDouble(arr[i].toString()) >= 0)
   temp = temp - Double.parseDouble(arr[i].toString());
   l.add(arr[i]);
   l.addAll(subtractor(arr,temp,--i));
  else
   
   l.addAll(subtractor(arr,temp,--i));
  
  return l;
 

运行结果:

请输入一组数字:按q停止输入:
1
你当前输入了1,当前的数字集合为:[1.0]
2
你当前输入了2,当前的数字集合为:[1.0, 2.0]
3
你当前输入了3,当前的数字集合为:[1.0, 2.0, 3.0]
4
你当前输入了4,当前的数字集合为:[1.0, 2.0, 3.0, 4.0]
5q
请输入正确的数字!
q
平均数为:5.0
[4.0, 1.0],总和为:5.0
[2.0, 3.0],总和为:5.0

参考技术A import java.math.*;public class T2 public static void main(String[] args) int[] a = 34,3,99,82,62,20,57,12,48; long p = (1L<<a.length)-1; int sum=0; for(int i=0; i<a.length; i++) sum += a[i]; System.out.println( "sum = " + sum ); int sub = sum; for(long i=1; i<(1L<<a.length)-1; i++) int sum2 = 0; long j=i; int k=0; while(j>0) if((j&1L)==1L) sum2 += a[k]; k++; j>>=1; if( Math.abs(sum-2*sum2)<sub ) p = i; sub = Math.abs(sum-2*sum2); int k=0; sum = 0; while(p>0) if((p&1L)==1L) System.out.print( a[k] + "\t" ); sum += a[k]; k++; p>>=1; System.out.println( "=\t" + sum ); 本程序只支持最多64个整数,如果数更多,可采用BitSet来控制每个数的用与弃本回答被提问者和网友采纳

嵌入式 ARM 汇编编程例题(二维数组按规律求和,求两数 gcd / lcm,求数组 min / max,字符串复制,排序)

文章目录

期末上机考试题目!

(只能用纯 ARM 汇编…不能调用 C 语言 ><)

0x00. 整数加减乘除

	area test, code, readonly
	entry
	mov r0, #2
	mov r1, #8
	
getadd
	add r2, r1, r0     ; r2 = r1 + r0  
getsub
	sub r3, r1, r0     ; r3 = r1 - r0
getmul
	mul r4, r1, r0     ; r4 = r1 * r0
getdiv                 ; r5 = r1 / r0
	sub r1, r1, r0
	add r5, r5, #1
	cmp r1, #0
	bgt getdiv
stop 
	b stop
	end

r2 = r1 + r0 = 0x0A = 10 \\textr2 = r1 + r0 = 0x0A = 10 r2 = r1 + r0 = 0x0A = 10

r3 = r1 - r0 = 0x06 = 6 \\textr3 = r1 - r0 = 0x06 = 6 r3 = r1 - r0 = 0x06 = 6

r4 = r1 * r0 = 0x10 = 16 \\textr4 = r1 * r0 = 0x10 = 16 r4 = r1 * r0 = 0x10 = 16

r5 = r1 / r0 = 0x04 = 4 \\textr5 = r1 / r0 = 0x04 = 4 r5 = r1 / r0 = 0x04 = 4

0x01. 一维数组按某种规律求和

0x01.1 求 1~100 之和

代码

	area text, code, readwrite
	entry
	mov R0, #100        ; R0=100
	mov R1, #0          ; R1=0
loop
	add R1, R1, R0      ; R1=R1+R0
	subs R0, R0, #1     ; R0=R0-1
	cmp R0, #0          ; 根据下一条指令来对R0,0进行比较
	bne loop            ; bne: 若R0 ≠ 0, 跳转至loop函数处循环执行。否则,就跳过loop函数继续执行
	ldr R2, =result     
	str R1, [R2]        ; 把R1的值存到R2所指定的地址中
result
	dcd 0               
stop
	b stop
	end

运行结果

r1 = 0x00013BA = 5050

0x01.2. 求一维数组的和

结果放置在 0x300000

	area getsum, code, readonly
	entry
	ldr r0, =src
	ldr r5, =0x300000
	mov r3, #len       ; r3=len, 数组长度
	mov r1, #0       ; r1保存总和 
		
loop
	ldr r2, [r0]       ; r1为数组当前值
	add r1, r1, r2
	add r0, r0, #4     ; 地址指针r0后移1位
	sub r3, r3, #1     ; r3--
	cmp r3, #0
	bne loop
stop
	str r1, [r5]
	b stop
	
	area array, data, readwrite
src dcd 1, 2, 3, 4, 5, 6, 7, 8, 9
len equ 9
	
	end

运行结果

1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 = 45 1+2+3+4+5+6 +7+8+9=45 1+2+3+4+5+6+7+8+9=45

得到的结果 r1 = 0x02D = 45 \\textr1 = 0x02D = 45 r1 = 0x02D = 45

结果存放在 0x300000 处

0x01.2. 求一维数组的所有奇数的和

代码

	area getsum, code, readonly
	entry
	ldr r0, =src
	mov r3, #len       ; r3=len, 数组长度
	mov r1, #0       ; r1保存总和 
		
loop
	ldr r2, [r0]       ; r1为数组当前值
	and r5, r2, #1
	cmp r5, #0         
	addne r1, r1, r2   ; 如果是奇数就加上
	add r0, r0, #4     ; 地址指针r0后移1位
	sub r3, r3, #1     ; r3--
	cmp r3, #0
	bne loop
stop
	b stop
	
	area array, data, readwrite
src dcd 1, 2, 3, 4, 5, 6, 7, 8, 9
len equ 9
	
	end

1 + 3 + 5 +7 + 9 = 25 \\text1 + 3 + 5 +7 + 9 = 25 1 + 3 + 5 +7 + 9 = 25

得到的结果 r1 = 0x019 = 25 \\textr1 = 0x019 = 25 r1 = 0x019 = 25

0x02. 二维数组按某种规律求和

听说不考二维数组()

0x02.1. 求二维数组的和

0x02.2. 求二维数组的所有奇数的和

0x03. 求两数的最大公约数

使用更相减损术计算 gcd ⁡ \\gcd gcd

	area getgcd, code, readonly
	entry
	
start 
	mov r1, #50           ; r1 = 50
	mov r2, #30           ; r2 = 30
loop
	cmp r1, r2            
	subhi r1, r1, r2      ; 若r1>r2, r1=r1-r2
	subls r2, r2, r1      ; 若r1<r2, r2=r2-r1
	cmp r1, r2
	bne loop              ; 若 r1=r2, 退出循环
stop
	b stop
	
	end

运行结果


gcd ⁡ ( 30 , 50 ) = 10 \\gcd(30,50)=10 gcd(30,50)=10

r1 = r2 = gcd = 0x0A = 10 \\textr1 = r2 = gcd = 0x0A = 10 r1 = r2 = gcd = 0x0A = 10

0x04. 求两数的最小公倍数

代码

lcm ( a , b ) = a × b gcd ⁡ ( a , b ) \\textlcm(a,b)=\\cfrac a\\times b\\gcd(a, b) lcm(a,b)=gcd(a,b)a×b

	area getlcm, code, readonly
	entry
	
start 
	mov r1, #50           ; r1 = 50
	mov r2, #30           ; r2 = 30
	mul r3, r1, r2        ; r3 = r1 * r2
loop
	cmp r1, r2            
	subhi r1, r1, r2      ; 若r1 > r2, r1 = r1 - r2
	subls r2, r2, r1      ; 若r1 < r2, r2 = r2 - r1
	cmp r1, r2
	bne loop              ; 若 r1 = r2, 退出循环
lcm                       ; lcm = a * b / gcd(a, b) 
	sub r3, r3, r1        ; arm 没有出发操作,因此使用模拟除法
	add r4, r4, #1
	cmp r3, #0
	bgt lcm 
stop
	b stop
	
	end

运行结果

r 4 = 0 x 96 = 150 r4 = 0x96 = 150 r4=0x96=150

lcm(30, 50) = 150 \\textlcm(30, 50) = 150 lcm(30, 50) = 150

0x05. 对一维数组进行排序

0x05.1. 冒泡排序

代码

; 冒泡排序
	area sort, code, readonly
	entry 
start 
	mov R4, #0          ; R4=0 
	ldr R6, =src        ; R6=src ,此时R6指向数组的开头   
	add R6, R6, #len    ; R6=R6+len ,此时R6指向数组的末尾      
outer 
	ldr R1, =src        ; 开始外围循环  
inner
	ldr R2, [R1]        ; 获取地址R1中的数字       R2=a[i] 
	ldr R3, [R1, #4]    ; 获取R1的下一个地址的数字 R3=a[i+1] 
	cmp R2, R3          ; 根据下一条指令来对R2,R3进行比较 
	strgt R3, [R1]      ; 如果R2>R3:  
	strgt R2, [R1, #4]  ;     交换R2,R3地址 
	add R1, R1, #4      ; 地址指针R1后移一位 
	cmp R1, R6          ; 根据下一条指令来对R1,R6进行比较(R1: 当前位置, R6: 数组末尾)    
	blt inner           ; blt: 小于(有符号数)如果R1<R6, 则跳转至inner处继续循环执行inner
	
	add R4, R4, #4      ; R4=R4+4 全局指针后移一位
	cmp R4, #len        ; 根据下一条指令来对R4,len进行比较(R4: 当前位置, len: 数组长度)
	suble R6, R6, #4    ; 如果没有走到末尾
	ble outer           ; 跳转至outer处继续循环执行outer
stop
	b stop
	
	area array, data, readwrite
src dcd 2, 5, 3, 1, 11, 10, 20
len equ 7 * 4 

	end 

运行结果


R6 = src = 0x804C \\textR6 = src = 0x804C R6 = src = 0x804C

r6 \\textr6 r6 开始,排序结果为: 1 , 2 , 3 , 5 , 10 , 11 , 20 1, 2, 3, 5, 10, 11, 20 1,2,3,5,10,11,20

0x06. 求一维数组中的最大值 / 最小值

代码

	area getminmax, code, readonly
	entry
	ldr r0, =src
	mov r5, #len       ; r5=len, 数组长度
	ldr r7, [r0]       ; r7为最大值
	ldr r6, [r0]       ; r6为最小值
		
loop
	add r0, r0, #4     ; 地址指针r0后移1位
	ldr r1, [r0]       ; r1为数组当前值
	sub r5, r5, #1     ; r5--
	cmp r7, r1
	movcc r7, r1       ; 产生错位,也即r7<r1, 使得r7=r1
	cmp r6, r1
	movcs r6, r1       ; 未产生错位,也即r6>r1, 使得r6=r1
	cmp r5, #0
	bne loop
stop
	b stop
	
	area array, data, readwrite
src dcd 2, 5, 3, 1, 11, 10, 15
len equ 7
	
	end

运行结果

r6 \\textr6 r6 为最小值, r6 = 1 \\textr6 = 1 r6 = 1
r7 \\textr7 r7 为最大值, r7 = 0xF = 15 \\textr7 = 0xF = 15 r7 = 0xF = 15

0x07. 字符串的复制

0x07.1. 字符串的复制

    area strcpy, code, readonly
	entry  
	ldr r0, =src   
	ldr r1, =des  
loop
	ldrb r2, [r0], #1  
	strb r2, [r1], #1  
	cmp r2, #0   
	bne loop   
stop 
	b stop    
	   
	area string, data, readwrite   
src dcb "abcdefghijklmn\\0"
des dcb "" 

    end

0x07.2. 从某地址处连续读取复制 100 个字符到目的地址标号 DIST 处

		area strcpy, code, readonly
dist	dcb "123456789……01234567890" 
		entry 
strcpys  
        stmfd r13!,r0-r3
        mov r0, #0x400
        ldr r1,= dist
        mov r2,#100
loop   
        subs r2, r2, #1
        ldrb r3, [r0], #1
        strb r3,[r1],#1
        bne  loop
        ldmfd r13!,r0-r3
        mov pc, lr

        end 

以上是关于求java程序:输入n个正整数,分成两组求和,求两列数字组合使这两组的和最接近平均数的主要内容,如果未能解决你的问题,请参考以下文章

用java将一个正整数拆分成若干个正整数的和,问有多少种分法?

用java将一个正整数拆分成若干个正整数的和,问有多少种分法?

C语言求助,《求m和n之间的所有素数》

正整数拆分问题 将一个给定的正整数n拆分成若干个在a到b之间的正整数之和,有多少种拆法

c语言简单求和,编写程序:输入两个数,求两个数的和

python累计求和,编写一个程序,从键盘输入两个整数m和n,求m和n之间(包括m和n)