如何在Java中使用最少的if语句块简化一个方程?

huangapple go评论66阅读模式
英文:

How to simplify an equation by using min amount of if block in Java?

问题

``` (A, B, C) = (x, y, z),如果 (0 ≤ q < 5)
            (y, x, z),如果 (5 ≤ q < 10)
            (z, x ,y),如果 (10 ≤ q < 15)
            (z, y, x),如果 (15 ≤ q < 20)
            (y, z, x),如果 (20 ≤ q < 25)
            (x, z, y),如果 (25 ≤ q < 30)

是否有更好的方法来写这个方程的六个条件?

if(0 ≤ q && q < 1)
    A = x; B = y; C = z;
else if(1 ≤ q && q < 2)
   ...

<details>
<summary>英文:</summary>

I have the following equation and I am thinking that there may be an approach to simplify it:

(A, B, C) = (x, y, z), if (0 <= q < 5)
(y, x, z), if (5 <= q < 10)
(z, x ,y), if (10 <= q < 15)
(z, y, x), if (15 <= q < 20)
(y, z, x), if (20 <= q < 25)
(x, z, y), if (25 <= q < 30)


Is there a better way to write 6 condition for this equation? 

if(0 <= q && q < 1)
A = x; B 0 y; C = z;
else if(1 <= q && q < 2)
...


</details>


# 答案1
**得分**: 2

你可以使用一个switch语句来返回一个带有这些值的对象。在这里,我使用了一个record作为一个不可变的类。它也可以是一个普通的类。

record Data&lt;T&gt; (T A, T B, T C) {}

Data&lt;Integer&gt; d = getValues(10.6, 10,20,30);
System.out.println(d);
Data&lt;String&gt; d2 = getValues(9.3, &quot;One&quot;,&quot;Two&quot;,&quot;Three&quot;);
System.out.println(d2);

输出结果

Data[A=30, B=10, C=20]
Data[A=Two, B=One, C=Three]
  • q 强制转换为 int 将选择正确的情况
  • 然后只需返回与 q 值关联的对象
  • 如果 q 超出范围,将抛出异常。
public static &lt;T&gt; Data&lt;T&gt; getValues(double q, T x, T y, T z) {           
   return switch((int)(q/5)) {
         case 0 -&gt; new Data&lt;&gt;(y,x,z);
         case 1 -&gt; new Data&lt;&gt;(y,x,z);
         case 2 -&gt; new Data&lt;&gt;(z,x,y);
         case 3 -&gt; new Data&lt;&gt;(z,y,x);
         case 4 -&gt; new Data&lt;&gt;(y,z,x);
         case 5 -&gt; new Data&lt;&gt;(x,z,y);
         default -&gt; throw new IllegalArgumentException(&quot;参数超出范围 q = &quot; + q);
   
     };
}
英文:

You could use a switch statement to return an object with the values. Here I am using a record as an immutable class. It could also be a regular class.

record Data&lt;T&gt; (T A, T B, T C) {}

Data&lt;Integer&gt; d = getValues(10.6, 10,20,30);
System.out.println(d);
Data&lt;String&gt; d2 = getValues(9.3, &quot;One&quot;,&quot;Two&quot;,&quot;Three&quot;);
System.out.println(d2);

prints

Data[A=30, B=10, C=20]
Data[A=Two, B=One, C=Three]
  • casting q to an int will select the correct case
  • then just return the object associated with the value of q
  • Exception will be thrown if q is out of range.
public static &lt;T&gt; Data&lt;T&gt; getValues(double q, T x, T y, T z) {           
   return switch((int)(q/5)) {
         case 0 -&gt; new Data&lt;&gt;(y,x,z);
         case 1 -&gt; new Data&lt;&gt;(y,x,z);
         case 2 -&gt; new Data&lt;&gt;(z,x,y);
         case 3 -&gt; new Data&lt;&gt;(z,y,x);
         case 4 -&gt; new Data&lt;&gt;(y,z,x);
         case 5 -&gt; new Data&lt;&gt;(x,z,y);
         default -&gt; throw new IllegalArgumentException(&quot;Argument out of range q = &quot; + q);
   
     };
}

</details>



# 答案2
**得分**: 1

```java
假设 x、y 和 z 的值相对恒定,您可以创建一个映射将 q 值转化为 A、B、C 的特定分配。

    Map<Long,Assignment> map = new HashMap<>();
    map.put(0, new Assignment(x,y,z));
    map.put(1, new Assignment(y,x,z));
    ...
    map.put(5, new Assignment(x,z,y));
    
    public Assignment getAssignment(double q) {
      // 超出范围的 q 值返回 null
      return map.get((long)Math.floor(q));
    }
英文:

Assuming the x, y, and z values are somewhat constant, you could create a Map that translate the q value to a particular assignment of A, B, C.

Map&lt;Long,Assignment&gt; map = new HashMap&lt;&gt;();
map.put(0, new Assignment(x,y,z));
map.put(1, new Assignment(y,x,z));
...
map.put(5, new Assignment(x,z,y));

public Assignment getAssignment(double q) {
  // out of range values of q return null
  return map.get((long)Math.floor(q));
}

答案3

得分: 1

public class Foo {
private static final List library;
static {
library = new ArrayList();
library.add(new Foo(x, y, z, 0, 1));
library.add(new Foo(y, x, z, 1, 2));
library.add(new Foo(z, x, y, 2, 3));
library.add(new Foo(z, y, x, 3, 4));
library.add(new Foo(y, z, x, 4, 5));
library.add(new Foo(x, z, y, 5, 6));
};
public static Foo get(double val) {
for(Foo foo : library) {
if(foo.lower <= val && foo.upper > val)
return foo;
}
return null;
}
public final Object A,B,C;
private final double lower,upper;
private Foo(Object A, Object B, Object C, double lower, double upper) {
this.A = A;
this.B = B;
this.C = C;
this.lower = lower;
this.upper = upper;
}
}

Then you can access your values like this

Foo foo = Foo.get(1.5d);
foo.A; // y

英文:

Let me suggest a simple data structure:

public class Foo {
	private static final List&lt;Foo&gt; library;
	static {
		library = new ArrayList&lt;Foo&gt;();
		library.add(new Foo(x, y, z, 0, 1));
		library.add(new Foo(y, x, z, 1, 2));
		library.add(new Foo(z, x, y, 2, 3));
		library.add(new Foo(z, y, x, 3, 4));
		library.add(new Foo(y, z, x, 4, 5));
		library.add(new Foo(x, z, y, 5, 6));
	};
	public static Foo get(double val) {
		for(Foo foo : library) {
			if(foo.lower &lt;= val &amp;&amp; foo.upper &gt; val)
				return foo;
		}
		return null;
	}
	public final Object A,B,C;
	private final double lower,upper;
	private Foo(Object A, Object B, Object C, double lower, double upper) {
		this.A = A;
		this.B = B;
		this.C = C;
		this.lower = lower;
		this.upper = upper;
	}
}

Then you can acces your values like this

Foo foo = Foo.get(1.5d);
foo.A; // y

huangapple
  • 本文由 发表于 2023年4月6日 20:26:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/75949502.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定