Cal*_*r99 24 java if-statement fizzbuzz switch-statement
下面的程序可以根据需要运行,但是如何减少if语句的数量.有人告诉我,如果你的函数包含2个或更多if语句,那么你做错了.有什么建议?我尝试过使用switch语句,但由于案例不能成为布尔值,因此无效.
for(int i = 1; i < 100; i++)
{
if(i % 10 == 3)
{
System.out.println("Fizz" + "(" + i + ") 3%10");
}
if(i / 10 == 3)
{
System.out.println("Fizz" + "(" + i + ") 3/10");
}
if(i % 10 == 5)
{
System.out.println("Buzz" + "(" + i + ") 5%10");
}
if(i / 10 == 5)
{
System.out.println("Fizz" + "(" + i + ") 5/10");
}
if(i / 10 == 7)
{
System.out.println("Fizz" + "(" + i + ") 7/10");
}
if(i%10 == 7)
{
System.out.println("Woof" + "(" + i + ") 7%10");
}
if(i % 3 == 0)
{
System.out.println("Fizz" + "(" + i + ") 3%==0");
}
if(i % 5 == 0)
{
System.out.println("Buzz" + "(" + i + ")5%==0");
}
if(i % 7 == 0)
{
System.out.println("Woof" + "(" + i + ")7%==0");
}
if( (i % 7 !=0 ) && (i % 3 !=0 ) && (i % 5 !=0 )
&& (i % 10 !=3) && (i % 10 !=5 ) && (i%10 !=7 ) )
System.out.println(i);
}
Run Code Online (Sandbox Code Playgroud)
Joh*_*n B 49
如何为案例创建方法:
public void printIfMod(int value, int mod){
if (value % 10 == mod)
System.out.println(...);
}
public void printIfDiv(int value, int div){
if (value / 10 == div)
System.out.println(...);
}
Run Code Online (Sandbox Code Playgroud)
然后,而不是一堆if你有一组调用这两种方法.您甚至可以创建一个调用上述两种方法的方法.
public void printIf(int value, int div){
printIfMod(value, div);
printIfDiv(value, div);
}
for(int i = 1; i < 100; i++) {
printIf(i, 3);
printIf(i, 5);
....
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,ifs对我来说,数量比重复代码的数量少.
Sea*_*oyd 26
使用两个switch语句略有改进
switch(i / 10){
case 3: // do something
break;
case 5: // do something else
break;
case 7: // do something else
break;
}
switch(i % 10){
case 3: // do something
break;
case 5: // do something else
break;
case 7: // do something else
break;
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,每个除数你需要一个switch语句.
或者,你可以拥抱OOP并提出这样的抽象:
public abstract class Processor {
private final int divisor;
private final int result;
private final boolean useDiv; // if true, use /, else use %
public Processor(int divisor, int result, boolean useDiv) {
this.divisor = divisor;
this.result = result;
this.useDiv = useDiv;
}
public final void process(int i){
if (
(useDiv && i / divisor == result)
|| (!useDiv && i % divisor == result)
){
doProcess(i);
}
}
protected abstract void doProcess(int i);
}
Run Code Online (Sandbox Code Playgroud)
样品用法:
public static void main(String[] args) {
List<Processor> processors = new ArrayList<>();
processors.add(new Processor(10, 3, false) {
@Override
protected void doProcess(int i) {
System.out.println("Fizz" + "(" + i + ") 3%10");
}
});
// add more processors here
for(int i = 1; i < 100; i++){
for (Processor processor : processors) {
processor.process(i);
}
}
}
Run Code Online (Sandbox Code Playgroud)
mpr*_*vat 12
一般来说,拥有大量if语句的代码看起来很可疑.可疑并不一定意味着错误.如果问题陈述有不相同的条件要检查(即你不能对它们进行分组),那么你必须像你一样独立完成它们.
在你的情况下,你必须检查可分性而不能从另一个推断出一个(即如果x可以被7整除,它并不意味着它也可以被5整除,等等......).你正在使用的所有数字都是故意选择的素数,所以这就是你进入这个数字的原因.
例如,如果他们说过,请检查可分性为2,3和6.然后你可以先检查6,因为那时你也可以暗示2和3的可分性.反之亦然,检查2和3并暗示它也可被6整除.如果所有数字都是素数,那么你就不能暗示.所以你的代码必须单独检查所有内容.
一个积极的副作用是它使你的意图易于在你的代码中阅读(因为它都是明确的).
我的两分钱......
Enum非常适合这里.它们允许您将功能封装在一个位置,而不是将其传播到整个流控制中.
public class Test {
public enum FizzBuzz {
Fizz {
@Override
String doIt(int n) {
return (n % 10) == 3 ? "3%10"
: (n / 10) == 3 ? "3/10"
: (n / 10) == 5 ? "5/10"
: (n / 10) == 7 ? "7/10"
: (n % 3) == 0 ? "3%==0"
: null;
}
},
Buzz {
@Override
String doIt(int n) {
return (n % 10) == 5 ? "5%10"
: (n % 5) == 0 ? "5%==0"
: (n / 10) == 3 ? "3/10"
: (n / 10) == 5 ? "5/10"
: (n / 10) == 7 ? "7/10"
: null;
}
},
Woof {
@Override
String doIt(int n) {
return (n % 10) == 7 ? "7%10"
: (n % 7) == 0 ? "7%==0"
: null;
}
};
// Returns a String if this one is appropriate for this n.
abstract String doIt(int n);
}
public void test() {
// Duplicates the posters output.
for (int i = 1; i < 100; i++) {
boolean doneIt = false;
for (FizzBuzz fb : FizzBuzz.values()) {
String s = fb.doIt(i);
if (s != null) {
System.out.println(fb + "(" + i + ") " + s);
doneIt = true;
}
}
if (!doneIt) {
System.out.println(i);
}
}
// Implements the game.
for (int i = 1; i < 100; i++) {
boolean doneIt = false;
for (FizzBuzz fb : FizzBuzz.values()) {
String s = fb.doIt(i);
if (s != null) {
if ( doneIt ) {
System.out.print("-");
}
System.out.print(fb);
doneIt = true;
}
}
if (!doneIt) {
System.out.print(i);
}
System.out.println();
}
}
public static void main(String args[]) {
try {
new Test().test();
} catch (Throwable t) {
t.printStackTrace(System.err);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我已经开始写一个涉及代码的答案,但是很多人都打败了我.我要说的一件事尚未被提及,你所指的这个特定的代码度量被称为圈复杂度,并不是一个可怕的坏事.
简而言之,它指的是一个方法在执行时可以采用的不同路径的数量,虽然它在您发布的代码剪切中非常高,并且有很多很好的提示/解决方案来减少它已被建议,个人我认为即使在它的当前形式中,代码也是非常易读的 - 这是一个奖励.它可以减少相当数量并且仍然可读,但我的观点是,这样的指标并不是一切,有时可以更简单地获得大量if语句,因为它更具可读性 - 可读性降低了犯错误的可能性,并使调试更容易
哦,我会替换最后一节:
if( (i % 7 !=0 ) && (i % 3 !=0 ) && (i % 5 !=0 )
&& (i % 10 !=3) && (i % 10 !=5 ) && (i%10 !=7 ) )
System.out.println(i);
Run Code Online (Sandbox Code Playgroud)
通过使用布尔标志,例如replaced = true每当调用任何替换语句时,上述语句都会折叠为:
if (!replaced)
System.out.println(i);
Run Code Online (Sandbox Code Playgroud)
我会争辩说,你问的是错误的问题.我认为你应该问的问题是:"我怎样才能重写这段代码,以便人类更容易理解?"
信条"消除if语句"是实现这一目标的一般想法,但它在很大程度上取决于上下文.
可悲的事实是,许多答案以"使其更简单"的幌子模糊了这个非常简单的算法.永远不要引入一个对象来消除一些if语句.在我的工作中,大多数代码由比原始作者更少理解体系结构,数学和代码的人维护,因此引入额外的结构和复杂性以将代码从50个物理行减少到30个物理行,但使其成为4时间更难理解不是胜利.
你的代码是重复的.使用循环为您重构它:
for (int i = 1; i < 100; i++) {
boolean found = false; // used to avoid the lengthy test for "nothing found"
for (int j = 3; j <= 7; j += 2) { // loop 3, 5, 7
if (i % 10 == j) {
System.out.println("Fizz" + "(" + i + ") "+j+"%10");
found = true;
}
if (i / 10 == j) {
System.out.println("Fizz" + "(" + i + ") "+j+"/10");
found = true;
}
if (i % j == 0) {
System.out.println("Fizz" + "(" + i + ") "+j+"%==0");
found = true;
}
}
if (!found) {
System.out.println(i);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15729 次 |
| 最近记录: |