如何处理算法?哪种方式首选?

时间:2012-01-09 15:46:40

标签: java algorithm

所以我正在学习Java并做一些基本算法(对此仍然很新)。

假设要求是反转5143的整数,使其变为3415

以下哪项是更好的方法(或者有更好的方法)?两个不同的函数是reverse()和reverseNum(忽略0值的能力被忽略):

public class ReverseIntegers {

public static void main(String[] args) {

reverseNum(5143);
reverse(5143);

}

public static void reverse(int number) {

    String numString = Integer.toString(number);
    String result = "";

    char[] cArray = numString.toCharArray();

    for (int i = (cArray.length - 1); i >= 0; i--) {
        result += Character.toString(cArray[i]);    // concatenate the String numbers in reverse order

    }

    System.out.println(Integer.parseInt(result));

}

public static void reverseNum(int number) {

    int numLength = Integer.toString(number).length();

    int[] numArray;
    numArray = new int[numLength];

    int numMod;
    int numModLength;
    int result = 0;


    for (int i = numLength - 1; i >= 0; i--) {

        numMod = (int)(number % Math.pow(10, i + 1));    // eliminate first integer value one by one
        numModLength = Integer.toString(numMod).length();

        while (numModLength > 1) {    // obtain the first integer value of the remainder
            numMod = (numMod / 10); 
            numModLength--;
        }

        numArray[i] = numMod;    // assign the first integer value to the array
    }

    int digits = numArray.length - 1;

    for (int i = 0; i < numArray.length; i++) {    // put numbers in the array in reverse sequence

        result += numArray[i] * Math.pow(10, digits);
        digits--;

    }

    System.out.println(result);

}
}

7 个答案:

答案 0 :(得分:5)

第一个功能大致相当于:

String rev = new StringBuilder().append(number).reverse().toString();
System.out.println(Integer.parseInt(rev));

第二个功能(在我看来)很难阅读。由于重复调用Integer.toString(),它的效率也很低。

第三种替代方法(你还没有编码)是拥有一个纯粹基于整数数学并且根本不使用字符串的函数。它可能是最有效的。但是,它需要注意如何处理以零结尾的数字。

在我看来,比赛是在第一和第三选择之间;第二个功能既有缺点也有两者的优点。

如果没有任何进一步的信息,我可能会在本回答的开头使用该代码,并将其替换为不使用字符串的内容,当且仅当 分析应用程序表明它值得做。

答案 1 :(得分:4)

这个怎么样:

public static int reverseInt(int n)
{
    int result = 0;
    while(n != 0)
    {
        result *= 10;
        result += (n % 10);
        n /= 10;
    }

    return result;
}

答案 2 :(得分:1)

在分析算法时,请考虑以下(以及其他因素取决于您的具体情况):开发工作量,资源成本和可维护性。

  • 开发工作 - 创建哪个更困难/更耗时?你必须回答这个问题。这可以通过更优雅的(StringBuffer.reverse())解决方案来解决吗?

  • 资源成本 - 似乎第一个在大多数情况下更便宜(乍一看,我可能是错的),但这在很大程度上取决于你的问题(通常他们有相同的复杂性,这里第一个可以如果使用StringBuffer,则减少为O(N),但目前第二种算法在此获胜。

例如,选择可能会根据有多少位数而改变,这可能导致非常大的N(数字)时的内存或时间问题。对于小问题,资源成本通常不重要(您是否会一直运行?如果您对资源成本投入过多,则需要增加开发工作量。这就是为什么经常建议在出现资源问题时进行优化的原因。

如果你真的需要知道并且无法通过算法分析来确定,那么本能应该始终以经验测试代码。

  • 可维护性 - 有人其他查看您的代码是否能够快速了解并更改它?对我来说,第一个算法的简单性获胜(到目前为止)。

答案 3 :(得分:0)

更好的方式:

new StringBuilder("" + number).reverse().toString()

答案 4 :(得分:0)

我建议总是检查现有的API,因为通常有一些方便的方法。像:

StringBuffer.reverse()

答案 5 :(得分:0)

接近算法的最佳方法是认识到算法测量的东西与程序的正确性不同。

假设两个程序都提供相同的输出,你能证明一个程序在某些情况下表现更好吗?如果可以,那么你已经提出一个论点,即在这种情况下它是更好的算法。只要这些情况成立,解决方案的实施将是更好的计划。

一个很好的例子是地址簿。非常简单的地址簿只是笔记本。地址在收到时写入。一个更复杂的地址簿打印有页面,可以通过字母表轻松编制索引。

如果您只写下地址,并且很少查找它们,那么未排序的地址簿可能比您必须跳转到正确字母的地址簿更快。如果您主要查找很少写下的地址,那么名称索引的地址簿显然更优越。如果你试图根据书中的名字来查找名字,那么未分类的地址簿比索引的地址簿更好(尽管面向日期的地址簿可能更好)。

所以要知道你理解算法领域要分析的内容,唯一的诀窍是你必须善于以数学方式描述操作,并证明你的观点不仅仅是轶事。

答案 6 :(得分:0)

使用字符串操作可以获得相同的结果:

int n = 5143;
String nStr = Integer.toString(n);
String nStrRev = new StringBuilder(nStr).reverse().toString();
int nRev = Integer.parseInt(nStrRev); // nRev == 3415