推荐.NET教程: ASP.NET C# 开发环境 Ajax教程 控件开发 统计报表 数据库 Web服务 安装部署 CommunityServer NHibernate DataGrid/GridView 实用代码 VS2005
示例源码 MVC/三层 SqlHelper 入门源码 开源 CMS Ajax/Atlas C#.net 毕业设计 源码 经典代码 商业 本站作品 持久层 随书源码 WebService 英文/汉化 Asp.net2.0

阿牛·乐园

每天进步一点点

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  80 随笔 :: 14 文章 :: 389 评论 :: 13 引用
  单位让生成一批卡,但不能带4.
  如想想生成1000张卡,想到的解决方法有两个:
  方法一:
    用一个while循环,先生成10进制字串,如果字串中包含4,跳过,然后继续. 直到生成1000张卡为止,跳出循环.
  方法二:
    用一个for循环,把每个数字转换成不包含4的进制数,完成

  看来,方法二要感觉要简单点. 且不用浪费空循环了,如(400-499)这一百次.
  要使用方法二,我们先要实现这个任意字符组成的任意进制的转换类.下面是我的实现:
    public class BaseConverter
    
{
        
protected List<char> _chars = new List<char>();
        
protected Dictionary<charint> _charmap = new Dictionary<charint>();
        
protected List<long> _preBitValue = new List<long>();

        
/// <summary>
        
/// 得到进制指定权位的值
        
/// </summary>
        
/// <param name="pos">权位</param>
        
/// <returns>权位的数值</returns>

        protected long GetPowerValue(int pos)
        
{
            
if (_preBitValue.Count < pos)
            
{
                
for (int i = _preBitValue.Count; i <= pos; ++i)
                
{
                    _preBitValue.Add(Convert.ToInt64(Math.Pow(_chars.Count, i)));
                }

            }


            
return _preBitValue[pos];
        }


        
/// <summary>
        
/// 构造一个指定进制和字符的转换器
        
/// </summary>
        
/// <param name="baseChars">表示从0-N的字符序列</param>

        public BaseConverter(char[] baseChars)
        
{
            _chars.AddRange(baseChars);

            
for (int i = 0; i < baseChars.Length; ++i)
            
{
                _charmap.Add(baseChars[i], i);
            }

        }


        
/// <summary>
        
/// 把用指定进制和字符的字串, 解释成等值的十进制数值
        
/// </summary>
        
/// <param name="value">指定进制和字符的字串</param>
        
/// <returns>等值的十进制数值</returns>

        public long ToNumber(string value)
        
{
            
char[] chars = value.ToCharArray();

            
long ret = 0;
            
for (int i = 0; i < chars.Length; ++i)
            
{
                ret 
+= GetPowerValue(chars.Length - 1 - i) * _charmap[chars[i]];
            }


            
return ret;
        }


        
/// <summary>
        
/// 把当前十进制数值用指定的进制和字符表现出来
        
/// </summary>
        
/// <param name="value">十进制数值</param>
        
/// <returns>表现出来的字串</returns>

        public string ToString(long value)
        
{
            
int power = _chars.Count;
            List
<char> list = new List<char>();

            
while (value > 0)
            
{
                
int l = Convert.ToInt32(value % power);
                value 
/= power;

                list.Add(_chars[l]);
            }


            list.Reverse();

            
return new string(list.ToArray());
        }

    }

   使用举例如下:
            //十进制转换
            BaseConverter bc = new BaseConverter("0123456789".ToCharArray());
            Console.WriteLine(bc.ToNumber(
"456789"));
            Console.WriteLine(bc.ToString(
756217));

            
//没有4的九进制转换
            bc = new BaseConverter("012356789".ToCharArray());
            
long val = bc.ToNumber("856789");
            Console.WriteLine(val);
            Console.WriteLine(bc.ToString(val));
            
            
//查看当前九进制下,两个号段之间有多少可用号
            long v1 = bc.ToNumber("018512");
            
long v2 = bc.ToNumber("999999");
            Console.WriteLine(
"还能有{0}张卡", v2 - v1);
            
            
//十六进制转换
            BaseConverter bcchs = new BaseConverter("0123456789abcdef".ToCharArray());
            Console.WriteLine(val);
            Console.WriteLine(bcchs.ToString(
0xefefef));
            
            
//下面看一下,都生成卡号从 3000000 开始的号,生成2000000 张
            {
                
//进制转换方法
                BaseConverter bc = new BaseConverter("012356789".ToCharArray());
                
long dtBegin = DateTime.Now.Ticks;

                
long min = bc.ToNumber("3000000");
                
long max = min + 2000000;

                
for (long i = min; i < max; ++i)
                
{
                    bc.ToString(i);
                }


                
long dtEnd = DateTime.Now.Ticks;
                Console.WriteLine(dtEnd 
- dtBegin);
            }

            
            
{
                
//普通方法
                long dtBegin = DateTime.Now.Ticks;
                
for (long i = 3000000, count = 0; count < 5000000++i)
                
{
                    
                    
string val = i.ToString();
                    
if (val.IndexOf('4'>= 0)
                        
continue;

                    
++count;
                }


                
long dtEnd = DateTime.Now.Ticks;
                Console.WriteLine(dtEnd 
- dtBegin);
            }


       由于中间有 4000000 的循环,所以还是进制转换方法优. 嘿嘿


PS:用这个方法,还可以用来加密哟:
   
            BaseConverter bcchs = new BaseConverter("ksdfhjiy&^$#@)(".ToCharArray());
            Console.WriteLine(bcchs.ToString(
895621));

//你猜一下,会是什么?

    
posted on 2007-07-09 16:51 阿牛 阅读(1567) 评论(9)  编辑 收藏 网摘 所属分类: ASP.netC#

评论

#1楼  2007-07-09 17:27 Anders Liu      
有点意思~ 但总感觉是不是复杂了点?还是需求没有描述清楚?
  回复  引用  查看    

#2楼  2007-07-09 18:05 股股 [未注册用户]
才1000张啊? 怪不得你用程序做。
用数据库做才快的嘛。我们随即生成100万8位数的数据, 不能重复, 不能包含4和7, 用SQL做, 很快的就出来的啦。
具体我就不说啦, 自己做才有乐趣。

  回复  引用    

#3楼  2007-07-09 18:17 风云(lovebanyi)      
不错..任意字符表示任意进制
  回复  引用  查看    

#4楼 [楼主] 2007-07-10 08:48 阿牛      
@股股
我晕,举例子是1000就1000张呀?
卡一生成,一般也是上万张


用什么语言做不重要,重要的是,实现的思想.对不?





  回复  引用  查看    

#5楼 [楼主] 2007-07-10 08:50 阿牛      
@Anders Liu

嘿嘿,需求很简单,只是实现的时候,不愿意写得太平庸,给自己个机会,享受思考的快乐.

  回复  引用  查看    

#6楼  2007-07-10 16:52 hoodlum1980      
看的很别扭,对此不予评论。
  回复  引用  查看    

来看热闹!唉,也只能是看热闹!
  回复  引用    

#8楼  2007-07-13 15:54 无忧浪子      
复杂,而且很慢
  回复  引用  查看    

#9楼 [楼主] 2007-07-13 17:51 阿牛      
@无忧浪子
请谈谈您的解法思路,大家学习讨论下?

  回复  引用  查看    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
Google站内搜索

China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
近千种 9-95 新二手计算图书火热销售中!
开发者征途系统新作:《设计模式——基于C#的工程化实现及扩展》



相关文章:

相关链接: