zoukankan      html  css  js  c++  java
  • 用"指定字符组成的任意进制"转换生成不带4的卡号

    单位让生成一批卡,但不能带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));

    //你猜一下,会是什么?
  • 相关阅读:
    Python字符编码补充
    shell脚本自动部署及监控
    【Linux】应用程序内存段布局
    【Linux】Core dump故障分析
    【Linux】GDB程序调试
    【Linux】小应用 大智慧
    【嵌入式】安装Linux系统到开发板
    【读书笔记】高效演讲
    【Linux】GCC编译
    【Linux】Linux 找回Root用户密码
  • 原文地址:https://www.cnblogs.com/evlon/p/811436.html
Copyright © 2011-2022 走看看