用HashMap写一个1-50的圆半径和面积(整数)

本文介绍了一个使用Java实现的圆面积计算程序,并通过JUnit框架进行单元测试的方法。程序利用HashMap存储不同半径对应的圆面积,展示了如何遍历Map并打印结果。此示例适用于初学者理解和实践Java的基本语法及单元测试。
package com.xatu.集合;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.junit.Test;

public class Cricle {
	@Test
	public void testCircle(){
		Map<Integer, Integer> c = new HashMap<>();
		for (int i = 0; i < 50; i++) {
			int r = i + 1;
			int s = (int) (r*r*Math.PI);
			c.put(r, s);
		}
		Set<Integer> keys = c.keySet();
		for (Integer key : keys) {
			Integer value = c.get(key);
			System.out.println(key+"--"+value);
		}
	}
}

 

我把格点改成double之后为什么选不出点也画不出图来了,画图的时候可以直接舍入到int,package com.smics.apps; import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.util.*; import java.util.stream.Collectors; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class BfsFindShot extends JFrame { public static void main(String[] args) { List<String> list1 = calcAllShot(); System.out.println("==========="); List<String> list2 = new BfsFindShot().selectPoints(list1,11); SwingUtilities.invokeLater(() -> { BfsFindShot visualizer = new BfsFindShot(); visualizer.addPoints(list1, list2); visualizer.setVisible(true); }); } private final List<Point> pointsList1 = new ArrayList<>(); private final List<Point> pointsList2 = new ArrayList<>(); public BfsFindShot() { setTitle("点分布预览"); setSize(800, 600); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); } public void addPoints(List<String> list1, List<String> list2) { pointsList1.clear(); pointsList2.clear(); for (String s : list1) pointsList1.add(parsePointAwt(s)); for (String s : list2) pointsList2.add(parsePointAwt(s)); DrawingPanel panel = new DrawingPanel(); panel.setSiteCount(list2.size()); add(panel); } private Point parsePointAwt(String s) { s = s.replaceAll("[{} ]", ""); String[] coords = s.split(","); return new Point( (int) Math.round(Double.parseDouble(coords[0])), (int) Math.round(Double.parseDouble(coords[1])) ); } class DrawingPanel extends JPanel { private int siteCount; // 新增:存储选点数 // 新增:设置选点数 public void setSiteCount(int count) { this.siteCount = count; } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); int centerX = getWidth() / 2; int centerY = getHeight() / 2; // 1. 动态获取并绘制同心 g.setColor(Color.BLUE); ZoneConfig config = CONFIG_MAP.get(siteCount); // 直接从常量配置获取 if (config != null) { for (double radius : config.radiusBounds) { int diameter = (int)(radius * 2); g.drawOval(centerX - (int)radius, centerY - (int)radius, diameter, diameter); } } // 2. 绘制坐标轴(保持不变) g.setColor(Color.LIGHT_GRAY); g.drawLine(0, centerY, getWidth(), centerY); g.drawLine(centerX, 0, centerX, getHeight()); // 3. 绘制点集(保持不变) g.setColor(Color.BLACK); for (Point p : pointsList1) { drawPoint(g, centerX + p.x, centerY - p.y); } g.setColor(Color.RED); for (Point p : pointsList2) { drawPoint(g, centerX + p.x, centerY - p.y); } } private void drawPoint(Graphics g, int x, int y) { g.fillOval(x - 3, y - 3, 6, 6); } } private static List<String> calcAllShot() { double radius = 150; double w = 24; double h = 28; double x0 = 0; double y0 = 0; List<String> rectangles = new ArrayList<>(); Set<String> visited = new HashSet<>(); Queue<double[]> queue = new LinkedList<>(); double startX = x0 - w / 2; double startY = y0 - h / 2; queue.offer(new double[]{startX, startY}); visited.add(formatKey(startX) + "," + formatKey(startY)); while (!queue.isEmpty()) { double[] current = queue.poll(); double x = current[0]; double y = current[1]; // 四个角坐标 boolean allInCircle = isInCircle(x, y, radius) || isInCircle(x + w, y, radius) || isInCircle(x, y + h, radius) || isInCircle(x + w, y + h, radius); if (allInCircle) { rectangles.add("{" + format(x) + "," + format(y) + "}"); double[][] directions = { {-w, 0}, {w, 0}, {0, -h}, {0, h} }; for (double[] dir : directions) { double nx = x + dir[0]; double ny = y + dir[1]; String key = formatKey(nx) + "," + formatKey(ny); if (!visited.contains(key)) { visited.add(key); queue.offer(new double[]{nx, ny}); } } } } rectangles.sort((a, b) -> { double x1 = parseX(a); double y1 = parseY(a); double x2 = parseX(b); double y2 = parseY(b); if (x1 != x2) { return Double.compare(x1, x2); } else { return Double.compare(y1, y2); } }); for (String rect : rectangles) { System.out.println(rect); } return rectangles; } private static double parseX(String s) { int commaIndex = s.indexOf(','); return Double.parseDouble(s.substring(1, commaIndex)); } private static double parseY(String s) { int commaIndex = s.indexOf(','); int endIndex = s.length() - 1; return Double.parseDouble(s.substring(commaIndex + 1, endIndex)); } public static boolean isInCircle(double x, double y, double radius) { return x * x + y * y <= radius * radius; } private static String format(double value) { return String.format("%.6f", value); } private static String formatKey(double value) { return String.format("%.6f", value).replaceAll("0*$", "").replaceAll("\\.$", ""); } // 配置定义(选点数 -> [圈半径边界, 圈选点数]) private static final Map<Integer, ZoneConfig> CONFIG_MAP = new HashMap<>(); static { // 13点:5圈(30/60/90/120/140)1/2/2/4/4 CONFIG_MAP.put(13, new ZoneConfig( new double[]{30, 60, 90, 120, 140}, new int[]{1, 2, 2, 4, 4} )); // 11点:5圈(30/60/90/120/140)1/1/3/4/2 CONFIG_MAP.put(11, new ZoneConfig( new double[]{30, 60, 90, 120, 140}, new int[]{1, 1, 3, 4, 2} )); // 9点:3圈(45/95/140)1/4/4 CONFIG_MAP.put(9, new ZoneConfig( new double[]{45, 95, 140}, new int[]{1, 4, 4} )); // 5点:3圈(45/95/140)1/2/2 CONFIG_MAP.put(5, new ZoneConfig( new double[]{45, 95, 140}, new int[]{1, 2, 2} )); } public List<String> selectPoints(List<String> pointStrings, int siteCount) { ZoneConfig config = CONFIG_MAP.get(siteCount); if (config == null) throw new IllegalArgumentException("不支持的点数配置"); // 解析点数据 List<ShotPoint> allPoints = pointStrings.stream() .map(this::parsePoint) .filter(Objects::nonNull) .filter(p -> p.radius <= config.outerRadius()) .collect(Collectors.toList()); // 生成半径分区 List<RadiusRing> rings = createRings(config, allPoints); // 计算动态角度偏移(自动交错) double[] angleOffsets = calculateAngleOffsets(rings); // 分层选点 return selectPointsFromRings(rings, angleOffsets); } //======================== 核心算法 ========================// private List<RadiusRing> createRings(ZoneConfig config, List<ShotPoint> points) { List<RadiusRing> rings = new ArrayList<>(); double prevBoundary = 0; for (int i = 0; i < config.radiusBounds.length; i++) { double lower = prevBoundary; double upper = config.radiusBounds[i]; double target = (lower + upper) / 2; // 目标半径(相邻圈平均值) List<ShotPoint> ringPoints = points.stream() .filter(p -> p.radius >= lower && p.radius <= upper) .collect(Collectors.toList()); rings.add(new RadiusRing( ringPoints, config.pointCounts[i], target )); prevBoundary = upper; } return rings; } private double[] calculateAngleOffsets(List<RadiusRing> rings) { double[] offsets = new double[rings.size()]; int prevStep = 0; int step = 0; for (int i = 0; i < rings.size(); i++) { step = rings.get(i).targetCount; if (i == 0) { offsets[i] = 0; // 最内层不偏移 } else { // 自动计算偏移量:内层角度步长的一半 if(prevStep == 1) { if(step == 1) { offsets[i] = 180; }else if (step == 2) { offsets[i] = 90; }else if (step == 3) { offsets[i] = 60; }else if (step == 4) { offsets[i] = 45; } }else if (prevStep == 2) { if(step == 2) { offsets[i] = 90; }else if (step == 4) { offsets[i] = 45; } }else if (prevStep == 3) { if(step == 4) { offsets[i] = 15; } }else if (prevStep == 4) { if(step == 2) { offsets[i] = 45; }else if (step == 4) { offsets[i] = 45; } } offsets[i] += offsets[i-1]; } prevStep = step; } return offsets; } private List<String> selectPointsFromRings(List<RadiusRing> rings, double[] angleOffsets) { List<String> result = new ArrayList<>(); for (int i = 0; i < rings.size(); i++) { RadiusRing ring = rings.get(i); if (ring.points.isEmpty()) continue; // 特殊处理:最内环选中心点 if (i == 0 && ring.targetCount == 1) { ShotPoint center = ring.points.stream() .min(Comparator.comparingDouble(p -> p.radius)) .orElse(ring.points.get(0)); result.add(center.original); continue; } // 通用环形选点 result.addAll(selectRingWithOffset( ring.points, ring.targetCount, angleOffsets[i], ring.targetRadius )); } return result; } private List<String> selectRingWithOffset( List<ShotPoint> points, int count, double offset, double targetRadius ) { List<String> selected = new ArrayList<>(); List<ShotPoint> candidates = new ArrayList<>(points); double angleStep = 360.0 / count; for (int i = 0; i < count; i++) { if (candidates.isEmpty()) break; double targetAngle = (i * angleStep + offset) % 360; // 角度优先级高于半径 ShotPoint best = candidates.stream() .min(Comparator.<ShotPoint>comparingDouble(p -> circularDistance(p.angle, targetAngle) // 第一优先级:角度匹配 ).thenComparingDouble(p -> Math.abs(p.radius - targetRadius) // 第二优先级:半径匹配 )) .orElse(null); if (best != null) { selected.add(best.original); candidates.remove(best); } } return selected; } //======================== 工具方法 ========================// private ShotPoint parsePoint(String s) { try { String clean = s.replaceAll("[{}]", ""); String[] coords = clean.split(","); int x = Integer.parseInt(coords[0].trim()); int y = Integer.parseInt(coords[1].trim()); return new ShotPoint(x, y, s); } catch (Exception e) { return null; } } private double circularDistance(double a, double b) { double diff = Math.abs(a - b) % 360; return Math.min(diff, 360 - diff); } //======================== 数据结构 ========================// static class ZoneConfig { final double[] radiusBounds; // 圈半径边界 final int[] pointCounts; // 每圈选点数 final double outerRadius; // 最大半径 ZoneConfig(double[] radiusBounds, int[] pointCounts) { this.radiusBounds = radiusBounds; this.pointCounts = pointCounts; this.outerRadius = radiusBounds[radiusBounds.length - 1]; } double outerRadius() { return outerRadius; } } static class RadiusRing { final List<ShotPoint> points; final int targetCount; final double targetRadius; RadiusRing(List<ShotPoint> points, int targetCount, double targetRadius) { this.points = points; this.targetCount = targetCount; this.targetRadius = targetRadius; } } static class ShotPoint { final int x, y; final double radius; final double angle; final String original; ShotPoint(int x, int y, String original) { this.x = x; this.y = y; this.original = original; this.radius = Math.sqrt(x*x + y*y); this.angle = (Math.toDegrees(Math.atan2(y, x)) + 360) % 360; } } }
最新发布
10-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值