老赵的自然数分解——少侠之对象解
自然数分解算法的起因介绍,老赵
前几天贴了个非递归的 今天继续搞一个使用对象的解
坚持用对象来解决问题的一个原因,是想证明使用面向对象不是造成算法速度慢的根本原因
例如,我这个面向对象的解,其运行速度似乎很牛的说,至少比我自己的非递归解要快10%。
核心类Item,代表算式中的每个项
派生类Tail,是最末尾的一项
主控类Splitter,负责构造以及输出
嫌文章太长的直接看源代码
另外,Cat Chen的代码要简洁得多了,值得学习。 并且对于本问题的分析也比我说得要更清晰。
delegate void OverflowEventHandler();
delegate void AddedEventHandler(Item item);
class Item
{
//回溯起点对象
public static Item StartItem { get; set; }
//总项数,最大值,最小值
public static int N { get; set; }
public static int Max { get; set; }
public static int Min { get; set; }
public static int Count { get; set; }
//事件
public event OverflowEventHandler Overflow;
public event AddedEventHandler Added;
//
private int _index, _remainN;
private int _subSum;
protected int _value;
//仅为了给尾部对象读取
public int SubSum { get { return _subSum; } }
public Item() { }
public Item(int index,ref int sum)
{
_index=index;
_remainN = (N - index-1 );
if (sum <= _remainN * Max)
{
_value = Min;
}
else
{
_value = sum - _remainN * Max;
}
//检查并设置回溯位置
CheckState(sum);
sum -= _value;
_subSum = sum;
}
public void Add()
{
if (_value < (_subSum + _value) / (_remainN + 1))
{//如果没有达到当前位置的最大允许值,递增自身
_value++;
_subSum--;
CheckState(_subSum);
//引发增加事件
Count++;
if (Added != null)
Added(this);
}
else
{//如果达到当前位置的最大允许值,引发溢出事件
if (Overflow != null)
{
Overflow();
}
}
}
public virtual void Reset(Item item)
{
//计算新的当前值
_value = item._subSum < _remainN * Max ? Min : item._subSum - _remainN * Max;
_value = Math.Max(_value, item._value);
_subSum = item._subSum-_value;
CheckState(_subSum);
Count++;
if (Added != null)
Added(this);
}
public override string ToString()
{
return _value.ToString();
}
private void CheckState(int sum)
{
//如果当前值小于允许最大值,则当前位置是回溯位置
if (_value < (sum + _value) / (_remainN + 1))
StartItem = this;
}
}
class Tail:Item
{
public new event AddedEventHandler Added;
public Tail(int sum)
{
_value = sum;
}
public override void Reset(Item item)
{
_value = item.SubSum;
if (Added != null)
Added(this);
}
}
class Splitter
{
//项目数足
Item[] _items;
StringBuilder _builder;
//记录当前结果,并引发下一次计算
void Splitter_Added(Item item)
{
_builder.AppendLine(string.Join("+",Array.ConvertAll(_items,i=>i.ToString())));
Item.StartItem.Add();
}
//第一个个项产生溢出,设置起点为空,终止计算
void Splitter_Overflow()
{
Item.StartItem = null;
}
public string PrintDivision(int sum, int n, int min, int max)
{
string returnValue = "";
Item.N = n;
Item.Max = max;
Item.Min = min;
_builder = new StringBuilder();
_items = new Item[n];
int i;
//构造项目数组
for (i = 0; i < n-1; i++)
{
_items[i] = new Item(i,ref sum);
if (i > 0)
{
//关联前后项目的事件
_items[i - 1].Added += _items[i].Reset;
_items[i].Overflow += _items[i - 1].Add;
}
}
//增加尾项目对象及其事件关联
_items[i] = new Tail(sum);
_items[i - 1].Added += _items[i].Reset;
//第一项溢出事件关联
_items[0].Overflow += new OverflowEventHandler(Splitter_Overflow);
//最后一项置位完成事件关联
_items[n - 1].Added += new AddedEventHandler(Splitter_Added);
//在存在未溢出位置时一直循环
while(Item.StartItem!=null)
//这里实参是不需要的,不想继续优化了,呵呵
Splitter_Added(_items[n - 1]);
//记录最后一次的结果
returnValue = _builder.ToString();
Console.WriteLine(Item.Count);
return returnValue;
}
}
class Program
{
static void Main(string[] args)
{
TimeSpan ts;
System.IO.StreamWriter w ;
string st;
DateTime dt;
w = new System.IO.StreamWriter("output.txt");
Splitter s = new Splitter();
dt = DateTime.Now;
st = s.PrintDivision(80, 25, 1, 30);
ts = DateTime.Now - dt;
Console.WriteLine( ts.TotalMilliseconds);
w.Write(st);
w.Close();
}
}
谢谢大家观赏
源代码
老赵的自然数分解——少侠之对象解相关推荐
- 【转载】Erlang精彩讨论-回“老赵”关于“Erlang中最大的问题”
原文:http://erlang-china.org/study/puzzle-in-erlang_pattern_match.html/comment-page-1#comments http:// ...
- 老赵谈IL(3):IL可以看到的东西,其实大都也可以用C#来发现
在上一篇文章中,我们通过一些示例谈论了IL与CLR中的一些特性.IL与C#等高级语言的作用类似,主要用于表示程序的逻辑.由于它同样了解太多CLR中的高级特性,因此它在大部分情况下依旧无法展现出比那些高 ...
- 艾伟:老赵谈IL(3):IL可以看到的东西,其实大都也可以用C#来发现
在上一篇文章中,我们通过一些示例谈论了IL与CLR中的一些特性.IL与C#等高级语言的作用类似,主要用于表示程序的逻辑.由于它同样了解太多CLR中的高级特性,因此它在大部分情况下依旧无法展现出比那些高 ...
- 把老赵的页面缓存片断改一下,呵呵
老赵同志写的页面缓存片断不错,用着方便,但我感觉在前端调用上有些不便,可以我把他的代码又改了一下,呵呵! 老赵代码的调用: Before Rendering: <%= DateTime.Now ...
- VS 2008的JavaScript代码提示功能 (学习老赵视频的笔记)
学习老赵的视频ASP.NET AJAX深入浅出系列课程(19):VS 2008的JavaScript代码提示功能(Level 200) 自己做的demo,记下来以便查阅!感谢赵老师! 原来js还可以像 ...
- 《老赵手动整理的Python笔记(一)》
<老赵手动整理的Python笔记(一)> 下面的内容的都是老赵在学习Python过程中记录的一些知识点,还有对于不理解的地方的一些研究.老赵有点强迫症,对于不明白的事情总想去弄明白,不然饭 ...
- 根据老赵轻量级Actor进行修改的Actor模型
学习了老赵轻量级Actor模型,并在实际中使用,效果不错. 老赵轻量级Actor模型: ActorLite:一个轻量级Actor模型实现(上) ActorLite:一个轻量级Actor模型实现(中) ...
- 解读网络“攻城狮”的发展---老赵带你铺一段路
成为网络工程师要学什么.如何学.在哪儿学,网络工程师的发展如何.薪资待遇如何等问题困扰着很多网络技术人员,尤其是正在学校苦苦寻求真理的同学们.我也是一名在校大学生,深知现在同学们的苦恼.如果能掌握关于 ...
- 用dotTace模仿下老赵的“使用Profiler分析程序性能”
最近看到老赵博客"使用Profiler分析程序性能"(http://www.cnblogs.com/JeffreyZhao/archive/2009/12/22/profiler- ...
最新文章
- 十、图像参数集Picture Paramater Set(PPS)解析
- 在北京,一款App从无到有至少需要100万?
- VS 中配置使用Visual SVN系列 三:TortoiseSVN Client(客户端)下载和安装
- input两种默认显示文字方式
- 数据挖掘-贝叶斯定理
- ubuntu下无法在根目录创建文件夹;permission denied 权限不足问题解决方法
- 【Fedora20】 samba配置
- Mr.J-- HTTP学习笔记(四)-- 连接管理
- Windows 平台下基于MinGW和Qt 的OpenCV 之CMake 项目配置
- javascript this
- Docker 之MySQL 重启,提示Error response from daemon: driver failed programming external connectivity on **
- 【ExtJS6开发日记(一)】——Chart类型无法加载,及ExtJS中出现requires无法加载情况的统一说明
- NR: PointA,offsetToPonitA,kSSB三者关系。
- GD32F4(3): 在keil软件中使用GD-LINK下载调试
- 给高科技强国的后来者埋下的痛
- 【论文翻译】Cluster Contrast for Unsupervised Person Re-Identification(2021)
- 大数乘法(快速傅立叶变换)下
- 网络基础之计算机网络参考模型(OSI参考模型与TCP/IP协议簇)
- 三井住友銀行相关资料
- [Cortex-M3]-0-M3介绍
热门文章
- java for循环迭代_JAVA中的for-each循环与迭代
- python输出质数序列_用python打印素数序列
- 串口 能 按位传输吗_六类网线能传输多少米?家装六类网线有必要吗?
- .NET Core 6.0之读取配置文件
- win8计算机安全模式,安全模式,教您Win8怎么进入安全模式
- django外调用url_Django学习(url配置及参数获取)
- 关于ValueError: Unknown projection ‘3d‘报错的解决方法
- python计算机_基础python计算机知识
- 计算机应用开设学校 四川,成都计算机类专业开设的院校有哪些
- 南华大学c语言多少分才能过_成人高考难吗?多少分可以过?