6

帮助我理解这段代码是如何工作的。它本质上是将逗号添加到一串数字中。因此,如果用户键入 1 到 3 位数字,则它不会改变。对于四位数字,它添加一个逗号,所以

  • 1111 变成 1,111
  • 11111 变成 11,111
  • 111111111 变为 11,111,111

等等。这是代码:

private String addCommasToNumericString (String digits)
{
    String result = "";
    int len = digits.length();
    int nDigits = 0;

    for (int i = len - 1; i >= 0; i--)                      
    {
        result = digits.charAt(i) + result;                 
        nDigits++;                                          
        if (((nDigits % 3) == 0) && (i > 0))                
        {
            result = "," + result;
        }
    }
    return (result);
}

我会解释我对它的理解

for循环主要计算用户写入的数字的长度,以避免在第一个数字之前放置逗号(例如,1111)。而 whilei小于它减去的字符串的长度1

result返回位置处的字符i,因为它向下计数,它从右向左返回“相反”的字符。

nDigits0在循环的每次迭代中将1 from 加到 的初始值上。

我想现在是我无法确切看到发生了什么的地方:if ("nDigits % 3) == 0

因此,对于通过循环的两次第一次迭代,它不会执行if循环,因为:

  • 1 % 3 = 1
  • 2 % 3 = 2
  • 3 % 3 = 0

nDigits开始是1因为循环nDigits++内的代码for,那么它如何将逗号放在三位而不是两位之后?它如何知道只有 4 位或 5 位数字可以将逗号正确地放置在位置 1 和 2 (1,111 - 11,111) 上?

4

6 回答 6

6

我认为解释这一点的最简单方法是在每次通过时减慢速度。

循环从字符串的末尾开始,所以如果你有字符串 12345,那么在第一次循环之后,结果将为“5”,nDigits 将为 1。

下一次,“4”将被添加到结果的前面,给你“45”,nDigits 将是 2。

第三次,它在结果前面添加“3”,使结果为“345”,然后 if-then 触发并在前面添加一个逗号。结果现在是“,345”。

更多通行证将为您提供“12,345”。

我认为让您感到困惑的是循环从“5”而不是“1”开始。一切都添加到结果的前面,而不是您通常期望的末尾。

希望这可以帮助!

于 2012-09-15T21:19:23.780 回答
2

这个方法的关键是从右到左数数。如果你不这样做,它就行不通。

您也可以使用字符串操作而不是字符操作来执行相同的操作。也许它更容易理解,所以我将提供一个例子。

我的解决方案涉及使用 subString 方法,并以与您类似的方式操作。从右到左开始,它将原始字符串分成两个子字符串,并在每次有 3 位数字组时在它们之间添加一个逗号。

private String addCommas (String digits) {

    String result = digits;

    if (digits.length() <= 3) return digits; // If the original value has 3 digits or  less it returns that value

    for (int i = 0; i < (digits.length() – 1) / 3; i++) {

      int commaPos = digits.length() – 3 – (3 * i); // comma position in each cicle

      result = result.substring(0, commaPos) + "," + result.substring(commaPos);
    }
   return result;
}
于 2013-05-21T20:03:49.177 回答
1

该变量result用于最终输出的增量构建,在每次迭代中,从左侧连接一个或两个字符(即从右到左构建字符串)。

  • 每次通过运行连接一个字符

    result = digits.charAt(i) + result;  
    

    这是实际数字

  • 第二个字符通过运行在每第三次迭代中连接

    result = "," + result;
    

    它是订单分隔符

该实现根本不是最优的,因为在 Java 中字符串是不可变的,result = "," + result;最终会创建一个新对象。StringBuffer或对于StringBuilder此目的更有效。

于 2012-09-15T21:21:26.780 回答
0
for (int i = len - 1; i >= 0; i--)

ilen - 1, 开头,从最后一位数字开始。i > 0inif (((nDigits % 3) == 0) && (i > 0))是在第一个数字之前避免逗号的那个(例如,1111)。

于 2012-09-15T21:17:27.900 回答
0

本质上,它的作用是从数字的最后一位开始并从右到左迭代,将它们添加到result字符串之前,并在每 3 个字符中放置一个逗号。

在这个特定的代码中,len保存数字的总长度,并且nDigits是已经评估了多少这些数字的计数。从位置len-1(即数字的最后一位数字的索引)开始,for 循环遍历位置 0(数字的第一位)。它获取 position 处的数字i,将其放在result字符串的前面,然后评估它前面是否应该有一个逗号。nDigits % 3将每 3 位返回 0,因此该if语句通过检查是否已写入 3 位并且您刚刚写入的数字不是 0 来评估是否应该有逗号。

于 2012-09-15T21:20:48.410 回答
0

为了我的目的,我修改了@Antonio Ricardo Diegues Silva 的答案。

/**
 * Get number in {@link String} with divider after 'n' number of digits
 * @param number number for processing
 * @param n amount after which will be inserted divider
 * @return {@link String} number with dividers
 */
public static <T extends Number> String insertDividerBetweenEveryNDigits(T number, int n, String divider) {
    StringBuilder builder = new StringBuilder().append(number);
    int digitsNumber = builder.length();
    if (digitsNumber > n) { // If the original value has n digits or less it just returns that value
        for (int i = 1; i <= (digitsNumber - 1) / n; i++) {
            int dividerPos = digitsNumber - (n * i); // divider position in each cycle
            builder.insert(dividerPos, divider);
        }
    }
    return builder.toString();
}
于 2016-08-12T13:53:07.943 回答