想让一个数拆成 y=2^n1+2^n2+……,这个算法实现心得
最开始,我尝试着用乘方来试探,比如用Math.Pow从0开始一直乘方下去,并加其和,直到小于y为止,可是这是个很荒谬的设计,结果当然有问题。
后来与各同行们探讨,有的建议递归,也有建议用数组,其实给我眼睛一亮的建议就是二进制。比如8=2^3,9=2^3+2^0,其实就是转换二进制的过程,8=1000,9=1001。这令我想到了当时学校的数学知识,这就是求得这个算法的最佳解决方案。
/// <summary>
/// Convert decimal number to y=2^n1+2^n2+……
/// </summary>
/// <param name="number">type:long</param>
/// <returns>note: return the string not the number</returns>
public static string ConvertToBinaryPower(long number)
{
//convert number to binary string
var strBinary = Convert.ToString(number, 2);
//define the result
var strResult = number + "=";
for (int i = strBinary.Length - 1, j = 0; i >= 0; i--, j++)
{
if (strBinary[i] == 49)//49 here is '1'
{
strResult += "2^" + j;
if (i > 0)//if is the last one, need not add '+'
{
strResult += "+";
}
}
}
return strResult;
}
以下是一个同事提供的方案,我做了部分性能上修改:
1 static string BuildString(long iNumber)
3 {
5 StringBuilder strResult =new StringBuilder(iNumber + "=");
7 for (var i = iNumber.ToString().Length * 4; i >= 0; i--)
9 {
11 if ((iNumber - (long)Math.Pow(2, i)) >= 0)
13 {
15 iNumber = iNumber - (long)Math.Pow(2, i);
17 strResult.Append("2^" + i.ToString() + "+");
19 }
21 }
23 strResult.Length--;
25 return strResult.ToString();
27 }
另外,十进制转换为二进制的自定义算法:(但是我上面没有用到这个自定义转换,不清楚与Convert.ToString(number, 2)相比哪个效率高)
1 /// <summary>
2 /// Convert decimal number to binary number
3 /// </summary>
4 /// <param name="number">decimal number</param>
5 /// <returns>return the binary number (type:string)</returns>
6 public static string ConvertDecimalToBinary(long number)
7 {
8 long[] temp = new long[100];//as the type is long, the length 100 is enough
9 //if 0, will not be converted
10 if (number == 0) return (number.ToString());
11 var i = 0;
12 while (number != 0)
13 {
14 temp[i++] = number % 2;
15 number /= 2;
16 }
17 var strBinary = "";
18 for (var j = 0; j <= i - 1; j++)
19 strBinary += (char)(temp[i - j - 1] + 48);//48 here means the char '0'
20 return (strBinary);
21 }