C#算法怎样才更快: 求 999999 的 1000次方 ,结果我用了15秒,真晕,高手进来帮忙支招啊

xinyun80 2008-05-30 04:46:08
我是用数组做的,在网上找了一些这方面的资料,但好多都是C 和C++版的
是不是要用到栈和指针啊

...全文
342 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
gyc 2008-06-24
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 JackLucifer 的回复:]


1).Net应该没有内置那么大的数据类型吧?

2)这是一个非常正确的方向。我觉得,…
[/Quote]

其实, 有个传说中的大数 BigNumber, 在.NET 3.5里面, 据说可以用到内存极限的大小(对于科学计算,天啊, 给多少个0啊)

不过,好像因为一些问题, 正式版的时候没有出来, 不过,之前写的一些BLog上面都有提及



另外,对于算法

我个人认为,需要把 减法,换成加法, 把除法 换成乘法
然后,加法,改成2的整数倍, 乘法改成符合 2的N次幂的形式

对于计算的方式,基本,就变成了, 移位操作了,这样应该快很多

另外,就是减少计算量,也是种方法
JackLucifer 2008-06-03
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 gyc 的回复:]
恩,
楼主可以看看CLR是如何工作的, 然后再来看待这个问题

除了算法, 还有实际中 建立对象的内存开销


————————
虽然,已经不碰数学有段时间了
不过还是提及一下

1、 你试试用内置的Math类中的Pow 方法
2、你可以使用Intel 或AMD官方给的 计算类库, 这个东西是对CPU最优化的
[/Quote]


1).Net应该没有内置那么大的数据类型吧?

2)这是一个非常正确的方向。我觉得,如果不是出于研究目的的话,完全可以借用第三方或开源的,相信开源中会有涉及大数计算的。就算没有c#的,也可以自己转换。更何况,c#可以调用c++的dll呢?
CODE163 2008-06-03
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 viena 的回复:]
要速度快,就不要用乘法!乘法比加法慢得多!
比如n*99就是 n*64+n*32+n*2+n
就是左移6位,加左移5位,加左移2位,加自身
[/Quote]

乘法转位运算有什么规律和特点
viena 2008-06-03
  • 打赏
  • 举报
回复
要速度快,就不要用乘法!乘法比加法慢得多!
比如n*99就是 n*64+n*32+n*2+n
就是左移6位,加左移5位,加左移2位,加自身
xinyun80 2008-06-03
  • 打赏
  • 举报
回复
上面的代码确实是编译通不过,而且有些看不懂,不过他的思路确实挺好的.
用二进制的做法至少比我用加减乘除算来得快
xinyun80 2008-06-02
  • 打赏
  • 举报
回复
你给的代码编译后不能通过,所以才问你怎么去调用
jianghao168 2008-06-01
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 vwxyzh 的回复:]
C# codepublic struct BigInteger
{
private short _sign;
private uint[] _data;

public static BigInteger Pow(BigInteger baseValue, BigInteger exponent)
{
if (exponent < 0)
throw new ArgumentOutOfRangeException("exponent", "NonNegative");
if (exponent == 0)
{
return One;
}
BigInteger integer = baseValue;
BigInteger result = One;
while (…
[/Quote]
这段代码编译不会通过啊!
vwxyzh 2008-05-31
  • 打赏
  • 举报
回复
哪里不明白?
xinyun80 2008-05-31
  • 打赏
  • 举报
回复
可是可以,但不能实现大数的相乘,而且要乘n次
xinyun80 2008-05-31
  • 打赏
  • 举报
回复
// other members, implement *, Square, RightShift, One (value is 1)
你的思路我懂了,但还不是太明白,大哥,麻烦详细一点
结合 999999 的 1000次方 做个示例,谢谢啊
gyc 2008-05-31
  • 打赏
  • 举报
回复
恩,
楼主可以看看CLR是如何工作的, 然后再来看待这个问题

除了算法, 还有实际中 建立对象的内存开销


————————
虽然,已经不碰数学有段时间了
不过还是提及一下

1、 你试试用内置的Math类中的Pow 方法
2、你可以使用Intel 或AMD官方给的 计算类库, 这个东西是对CPU最优化的
tober 2008-05-31
  • 打赏
  • 举报
回复
vwxyzh 2008-05-31
  • 打赏
  • 举报
回复

大整数类型 底 指数(只支持整数)
public static BigInteger Pow(BigInteger baseValue, BigInteger exponent)
{
// 指数小于0的情况
if (exponent < 0)
throw new ArgumentOutOfRangeException("exponent", "NonNegative");
// 指数等与0的情况
if (exponent == 0)
{
return One;
}
// 当前的底
BigInteger integer = baseValue;
// 结果
BigInteger result = One;
// 当指数大于0
while (exponent > 0)
{
// 任何整数都能用二进制表示
// 如果指数的最后一位是1,那么结果*=当前的底
if ((exponent._data[0] & 1) != 0)
{
result *= integer;
}
// 如果指数就是1,那么就返回
if (exponent == 1)
{
return result;
}
// 当前底=当前底的平方
integer = integer.Square();
// 指数=指数右移1位
exponent = RightShift(exponent, 1);
}
return result;
}
xinyun80 2008-05-31
  • 打赏
  • 举报
回复
朋友,可否简单说明一下
vwxyzh 2008-05-31
  • 打赏
  • 举报
回复
public struct BigInteger
{
private short _sign;
private uint[] _data;

public static BigInteger Pow(BigInteger baseValue, BigInteger exponent)
{
if (exponent < 0)
throw new ArgumentOutOfRangeException("exponent", "NonNegative");
if (exponent == 0)
{
return One;
}
BigInteger integer = baseValue;
BigInteger result = One;
while (exponent > 0)
{
if ((exponent._data[0] & 1) != 0)
{
result *= integer;
}
if (exponent == 1)
{
return result;
}
integer = integer.Square();
exponent = RightShift(exponent, 1);
}
return result;
}

// other members, implement *, Square, RightShift, One (value is 1)
}
ATGO 2008-05-30
  • 打赏
  • 举报
回复
C/C++ 大一时写的代码,实现了两个数相乘,用了int数组。摘自AC过的PKU 1001
不好的话请指出- -

int* multiplication(int *Result, const int len, const int *Source, const int lenght)
{
int i = 0;
int j = 0;
int temp[MAX_BIT] = {0};//临时储存
int array = 0;//进位
for (i=0; i<lenght; i++)
{
for (j=0; j<len; j++)
{
if (0 == i)
temp[j+i] = Result[j] * Source[i] + array;
else
temp[j+i] += Result[j] * Source[i] + array;
array = temp[j+i]/10;
temp[j+i] %= 10;
}
}
memcpy(Result, temp, len*sizeof(int));
return Result;
}

  • 打赏
  • 举报
回复
分解因数
xinyun80 2008-05-30
  • 打赏
  • 举报
回复
那要是999次方,又该怎么分解法呢
  • 打赏
  • 举报
回复
精确解法

999999^1000==(999999^2)^500==((999999^2)^2)^250==(((999999^2)^2)^2)^125==
((((999999^2)^2)^2)^5)^25=(((((999999^2)^2)^2)^5)^5)^5

这样简化之后次数就少多了。

不精确解法

用 对数

xinyun80 2008-05-30
  • 打赏
  • 举报
回复
你所推介的只是局限于乘法啊, 结果算下去时间可能会更长,在此基础上怎样优化,就是解决大数连乘的问题
加载更多回复(2)

17,740

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 .NET Framework
社区管理员
  • .NET Framework社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧