英文:
Fastest Way To Reverse Long Java
问题
什么是反转Long
值的最快方法?
例如,9876543210
应返回0123456789
。
这是我现在有的:
long n = 0, c = 987654321 * 10; // *10用于得到9876543210作为长整型值;
while (c > 0) n = n * 10 + c % 10;
System.out.println(n);
英文:
What's the fastest way to reverse a Long
value?
For example, 9876543210
should return 0123456789
.
This is what I have right now:
long n = 0, c = 987654321 * 10; // *10 is to get 9876543210 as long value;
while (c > 0) n = n * 10 + c % 10;
System.out.println(n);
答案1
得分: 3
您的程序陷入了一个无限循环,因为您从未更改c
的值。在每次迭代的末尾添加c /= 10
,它就会工作,尽管由于它是一个数字,前导零将被删除。
long n = 0, c = 9876543210L;
while (c > 0){
n = n * 10 + c % 10;
c /= 10;
}
System.out.println(n);
如果您需要保留前导零,您应该考虑使用String
。
long c = 9876543210L;
final StringBuilder sb = new StringBuilder();
while (c > 0){
sb.append(c % 10);
c /= 10;
}
System.out.println(sb.toString());
英文:
Your program encounters an infinite loop because you never change the value of c
. Add c /= 10
at the end of each iteration and it will work, albeit the leading zero will be dropped due to it being a number.
long n = 0, c = 9876543210L;
while (c > 0){
n = n * 10 + c % 10;
c /= 10;
}
System.out.println(n);
If you need to have the leading zero, you should consider using String
s instead.
long c = 9876543210L;
final StringBuilder sb = new StringBuilder();
while (c > 0){
sb.append(c % 10);
c /= 10;
}
System.out.println(sb.toString());
答案2
得分: 2
我认为这可以很快
long x = 1234567890L;
String reversed = new StringBuilder(Long.toString(x)).reverse().toString();
// reversed = "0987654321"
如果您想将反转后的值再次转换为long
:
long x = -1234567890000L;
StringBuilder reversed = new StringBuilder(Long.toString(x)).reverse();
System.out.println(reversed); // 0000987654321-
if (reversed.charAt(reversed.length() - 1) == '-') //删除最后位置的 `-`
{
reversed.setLength(reversed.length() - 1);
}
while (reversed.charAt(0) == '0') //删除开头的所有 `0`
{
reversed.replace(0, 1, "");
}
System.out.println(reversed); // 987654321
long newLong = Long.parseLong(reversed.toString());
英文:
I think this can be fast
long x = 1234567890L;
String reversed = new StringBuilder(Long.toString(x)).reverse().toString();
// reversed = "0987654321"
<hr>
If You want to convert a reversed value to a long
again:
long x = -1234567890000L;
StringBuilder reversed = new StringBuilder(Long.toString(x)).reverse();
System.out.println(reversed); // 0000987654321-
if (reversed.charAt(reversed.length() - 1) == '-') //remove `-` at last position
{
reversed.setLength(reversed.length() - 1);
}
while (reversed.charAt(0) == '0') //remove all `0` at the beginning
{
reversed.replace(0, 1, "");
}
System.out.println(reversed); // 987654321
long newLong = Long.parseLong(reversed.toString());
答案3
得分: 1
您可以简单地将其转换为字符串,然后再将字符串反转,特别是如果最终希望字符串输出。这应该相当简单,而且它包括了前导的0,这也可能比为每个位置进行计算更快(但是在valueOf中进行转换的成本可能会取消这个优势):
long c = 9876543210L;
String cAsString = String.valueOf(c);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < cAsString.length(); i++) {
builder.append(cAsString.substring(cAsString.length() - (i + 1), cAsString.length() - i));
}
System.out.println(builder.toString());
或者作为一行代码:
long c = 9876543210L;
String reverted = new StringBuilder(String.valueOf(c)).reverse().toString();
System.out.println(reverted);
我对当前答案选项进行了一些比较:
public static void main(String[] args) {
Instant start = Instant.now();
for (long i = 0; i < 100_000_000; i++) {
stringbuilderWithDirectCalcs(i);
}
Duration duration = Duration.between(start, Instant.now());
System.out.println("Took " + duration);
}
protected static void stringbuilderWithDirectCalcs(long value) {
final StringBuilder sb = new StringBuilder();
while (value > 0) {
sb.append(value % 10);
value /= 10;
}
// System.out.println(sb.toString());
}
protected static void stringbuilderConvenient(long value) {
String reverted = new StringBuilder(String.valueOf(value)).reverse().toString();
//System.out.println(reverted);
}
protected static void stringbuilderHandCrafted(long value) {
String cAsString = String.valueOf(value);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < cAsString.length(); i++) {
builder.append(cAsString.substring(cAsString.length() - (i + 1), cAsString.length() - i));
}
//System.out.println(builder.toString());
}
我进行了三次运行。结果如下:
stringbuilderConvenient
Took PT6.988S / Took PT6.8S / Took PT6.68S
stringbuilderWithDirectCalcs:
Took PT6.17S / Took PT6.776S / Took PT6.692S
stringbuilderHandCrafted
Took PT18.205S / Took PT16.035S / Took PT17.025S
因此,手动扫描字符串并逐步组装StringBuilder似乎不可行。显然,Stephen C在他的评论中是对的,即在转换为String时计算仍然会发生。但基于StringBuilder.reverse和手动计算每个位置的方法非常接近(任何差异可能是由于微小的运行时波动引起的)。因此,人们可以选择StringBuilder.reverse方法,以提高可读性,性能几乎相同。
英文:
You can simply convert to string and then revert the String, in particular if you want string output in the end anyway. This should be quite straight forward and it has the leading 0, it might also be faster than doing calculations for each positions (but the cost of conversion in valueOf might cancel that advantage):
long c = 9876543210L;
String cAsString = String.valueOf(c);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < cAsString.length(); i++) {
builder.append(cAsString.substring(cAsString.length() - (i + 1), cAsString.length() - i));
}
System.out.println(builder.toString());
or as a one liner
long c = 9876543210L;
String reverted = new StringBuilder(String.valueOf(c)).reverse().toString();
System.out.println(reverted);
I did a little comparison between the options of the current answers:
public static void main(String[] args) {
Instant start = Instant.now();
for (long i = 0; i < 100_000_000; i++) {
stringbuilderWithDirectCalcs(i);
}
Duration duration = Duration.between(start, Instant.now());
System.out.println("Took " + duration);
}
protected static void stringbuilderWithDirectCalcs(long value) {
final StringBuilder sb = new StringBuilder();
while (value > 0) {
sb.append(value % 10);
value /= 10;
}
// System.out.println(sb.toString());
}
protected static void stringbuilderConvenient(long value) {
String reverted = new StringBuilder(String.valueOf(value)).reverse().toString();
//System.out.println(reverted);
}
protected static void stringbuilderHandCrafted(long value) {
String cAsString = String.valueOf(value);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < cAsString.length(); i++) {
builder.append(cAsString.substring(cAsString.length() - (i + 1), cAsString.length() - i));
}
//System.out.println(builder.toString());
}
I did three runs each. The outcome:
stringbuilderConvenient
Took PT6.988S / Took PT6.8S / Took PT6.68S
stringbuilderWithDirectCalcs:
Took PT6.17S / Took PT6.776S / Took PT6.692S
stringbuilderHandCrafted
Took PT18.205S / Took PT16.035S / Took PT17.025S
So, scanning the String by hand and sticking the StringBuilder together step by step seems out of the question. Obviously Stephen C was right in his comment that the calculations happen anyway when converting to String. But the approach based on Stringbuilder.reverse and handcalculating each position are pretty close (and any difference might be due to minor runtime fluctuations). So, one might choose the StringBuilder.reverse method over calculating each position by hand for readability with about the same performance.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论