2011-11-08 29 views
3

給定兩個正整數x和y,我需要找到大於或等於x的下一個數,它是y的倍數。查找下一個多行的算法

例如:

X = 18,Y = 3 => 18

X = 18,Y = 5 => 20

X = 121,Y = 25 => 125

我首先想到的是保持遞增x,直到我找到了比賽,但能夠獲得較高的y值是非常低效的。

然後我想到了x - (x % y) + y,但是如果x是y的倍數,那就行不通。當然,我總是可以使用公式x - ((x % y)==0?y:x % y) + y中的三元運算符進行調整。

有沒有人有任何好的,聰明的,簡單的建議或完整的解決方案,比我所觸及的更好?我在邏輯中錯過了一些明顯的東西嗎?

我將使用Java(這是一個更大的算法的一小部分),但如果它是全數直接數學,僞代碼將同樣有用。

+3

其實我喜歡你的解決方案.. –

+0

我直覺想到了您的解決方案,有可能是其他智能招數,但我懷疑你會發現什麼都更有效。 –

+0

你可能會考慮提出這個上math.stackexchange.com –

回答

5

如果xy是正int當時的這將工作:

y * ((x-1)/y + 1); 

使用x-1讓您不必擔心特殊情況xy的倍數。例如,如果y = 5,然後16 <= x <= 20

15 <= x-1 <= 19 
(x-1)/y == 3 
(x-1)/y+1 == 4 
y*((x-1)/y+1) == 20 
+3

我一直認爲'y *((x + y-1)/ y)'比這更好。值是相同的,形式稍微乾淨。 –

+0

是的,無論哪種方式工作。 – JohnPS

+0

當我從答案中將測試類插入測試類時,您的答案似乎很好。另外,我喜歡它比我的三元解決方案更好。我認爲這個問題有不止一個正確的答案。 – smp7d

3

恩,那麼呢?

tmp = ceil(x/y); 
result = y * tmp; 
+1

'tmp'沒有必要。 – ThomasMcLeod

+3

如果'x'和'y'類型爲'int',這將不起作用。即'ceil(16/5)== ceil(3)== 3',所以你得到'5 * 3 == 15',但它應該是'20'。 – JohnPS

+0

我在已發佈的答案中將您的建議添加爲RecommendedFormula。我認爲JohnPS的評論可能是正確的。 – smp7d

1

假設x和y大於零。

的數學公式是很簡單: 的Ceil(X/Y)* Y

其中的Ceil(x)是大於或等於指定的實數

在最小積分值Java中,你可以使用函數Math.ceil()用於此目的: http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Math.html#ceil(double

+0

我在我發佈的答案中添加了您的建議作爲RecommendedFormula(與Pateman的答案相同)。我只是有錯誤的類型? – smp7d

0

感謝您的答覆。到目前爲止,我只有運氣與我的原始解決方案,但我仍然希望看到更好的東西。下面是我建,試圖幫助促進想法的簡單測試類:

package com.scratch; 

import java.util.ArrayList; 
import java.util.List; 

public class Test { 
    private static class Values { 
     long x; 
     long y; 
     long result; 

     Values(long x, long y, long result) { 
      this.x = x; 
      this.y = y; 
      this.result = result; 
     } 
    } 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     List<Values> list = new ArrayList<Values>(); 
     Values v1 = new Values(18, 3, 18); 
     list.add(v1); 
     Values v2 = new Values(18, 5, 20); 
     list.add(v2); 
     Values v3 = new Values(121, 25, 125); 
     list.add(v3); 
     Values v4 = new Values(9999999, 10, 10000000); 
     list.add(v4); 

     Operation operation = new MyFormula(); 
     // Operation operation = new RecommendedFormula(); 
      // Operation operation = new RecommendedFormula2(); 
     for (Values v : list) { 
      System.out.println(v.x + ", " + v.y + " => " + v.result + "?"); 
      long res = operation.perform(v.x, v.y); 
      System.out.println(res == v.result ? "worked" : "nope... Expected " 
        + v.result + ", got " + res); 
     } 
    } 

    private static interface Operation { 
     long perform(long x, long y); 
    } 

    private static class MyFormula implements Operation { 

     @Override 
     public long perform(long x, long y) { 
      return x - ((x % y) == 0 ? y : x % y) + y; 
     } 

    } 

    private static class RecommendedFormula implements Operation { 

     @Override 
     public long perform(long x, long y) { 
      return (long) (Math.ceil(x/y) * y); 
     } 

    } 

private static class RecommendedFormula2 implements Operation{ 

     @Override 
     public long perform(long x, long y) { 
      return x + (y - x % y) % y; 
     } 

    } 

} 

MyFormula(在這個問題),似乎工作得很好。RecommendedFormula沒有,但這可能只是因爲我使用的類型(這是我需要在成品中使用)。

+0

增加了RecommendedFormula2(來自對問題的評論)。看起來像贏家? – smp7d

+1

要使推薦模式正常工作,您必須在分割之前至少投一個x和y。即使那樣,它也會對大的x和/或y產生錯誤的結果。 –