zoukankan      html  css  js  c++  java
  • 支持位移操作的环形字符串

    引言

    偶然看到一个加密问题,说要把若干个整数按二进制样式做成首尾衔接的环,然后要查找这个环中0和1的数目,还要确定某个二进制的片段在整个环里不重复。

    我没有想得太细,只是想起了很早以前模拟大整数运算器时采取的一种原始方法—就是把数字转换为字符串,利用字符串拼接,人工地模拟二进制的位运算。于是想着做一个能支持位移的字符串,便有了下面这个小东西。

    当然,这个结构很不完善,一方面是支持的位数有限制,二是取值也还有一些障碍,权当一乐了。

    示例代码

    一、将uint转换为32位的二进制字符串的扩展类

    简单地利用“与”运算,按位生成uint值对应的二进制字符串。Convert.ToString(int value, int base)可以支持2/8/10/16四种进制。

    public static class UIntToBinString
    {   
        public static string ToBinString(this uint value)
        {
            StringBuilder result = new StringBuilder();
            for (int i = 0, mask = 1; i < 32; i++, mask <<= 1)
            {
                if ((value & mask) == mask)
                    result.Insert(0, '1');
                else
                    result.Insert(0, '0');
            }
    
            return result.ToString();
        }
    }

    二、对单个字符串实现位移的类

    声明一个位移处理的委托ShiftHandler,方便之后的处理。

    public class StringNode 
    {
        private string _value;
    
        public string Value
        {
            get { return _value; }
        }
    
        public delegate void ShiftHandler(int bit, ref string segment);
        public ShiftHandler LeftShiftHandler;
        public ShiftHandler RightShiftHandler;
    
        private StringNode()
        {
            this.LoadDefaultHandler();
        }
    
        public StringNode(string value)
            : this()
        {
            Debug.Assert(!string.IsNullOrEmpty(value), "Ctor does not accept empty or null string as para.");
            this._value = value;
        }
    
        private void LeftShift(int bit, ref string segment)
        {
            Debug.Assert(bit > 0, "para bit must be greater than zero.");
            Debug.Assert(!string.IsNullOrEmpty(segment), "para segment can not be empty or null.");
            Debug.Assert(bit == segment.Length, "length of para segment does not equals to bit.");
    
            string temp = this._value;
            this._value = temp.Substring(bit) + segment;
            segment = temp.Substring(0, bit);
        }
    
        private void RightShift(int bit, ref string segment)
        {
            Debug.Assert(bit > 0, "para bit must be greater than zero.");
            Debug.Assert(!string.IsNullOrEmpty(segment), "para segment can not be empty or null.");
            Debug.Assert(bit == segment.Length, "length of para segment does not equals to bit.");
    
            string temp = this._value;
            this._value = segment + temp.Substring(0, temp.Length - bit);
            segment = temp.Substring(temp.Length - bit);
        }
    
        public void LoadDefaultHandler()
        {
            this.LeftShiftHandler = new ShiftHandler(this.LeftShift);
            this.RightShiftHandler = new ShiftHandler(this.RightShift);
        }
    }

    三、对前一个类StringNode的升级和再封装

    把若干个字符串拼接起来,实现整体位移。

    public class StringQueue : List<StringNode>
    {
        public void LeftShift(int bit)
        {
            Debug.Assert(bit > 0, "para bit must be greater than zero.");
            string temp = this[0].Value.Substring(0, bit);
            this.AttachChain();
            this[0].LeftShiftHandler(bit, ref temp);
            this.DetachChain();
        }
    
        public void RightShift(int bit)
        {
            Debug.Assert(bit > 0, "para bit must be greater than zero.");
            string temp = this[this.Count-1].Value;
            temp = temp.Substring(temp.Length - bit);
            this.AttachChain();
            this[0].RightShiftHandler(bit, ref temp);
            this.DetachChain();
        }
    
        private void AttachChain()
        {    
            for (int i = 1; i < this.Count; i++)
            {
                this[0].LeftShiftHandler += this[i].LeftShiftHandler;
                this[0].RightShiftHandler += this[i].RightShiftHandler;
            }        
        }
    
        private void DetachChain()
        {
            this[0].LoadDefaultHandler();
        }
    
        public void DisplayValue()
        {
            Console.ForegroundColor = ConsoleColor.Yellow;
    
            foreach (StringNode node in this)
                Console.Write(node.Value);
            Console.WriteLine();
    
            Console.ForegroundColor = ConsoleColor.White;
        }
    }

    四、主程序示例

    static void Main(string[] args)
    {
        uint[] array = new uint[] { 1315, 34135, 133813, 80761 };
        StringQueue queue = new StringQueue();
    
        foreach (uint value in array)
            queue.Add(new StringNode(value.ToBinString()));
    
        Console.WriteLine("原始值");
        queue.DisplayValue();
        
        Console.WriteLine("右移6位");
        queue.RightShift(6);
        queue.DisplayValue();
    
        Console.WriteLine("左移11位");
        queue.LeftShift(11);
        queue.DisplayValue();
    
        Console.ReadLine();
    }

    五、运行结果

    原始值
    00000000000000000000101001000110000000000000000
    10000101010101110000000000000010000101010110101
    00000000000000010011101101111001
    右移6位
    11001000000000000000000000101001000110000000000
    00000010000101010101110000000000000100000101010
    11010100000000000000010011101101
    左移11位
    00000000000000010100111001000000000000000010000
    10101111001000000000000001000001101010001100000
    00000000001001110110101011100000
  • 相关阅读:
    networktool3
    networktool2
    networktool
    Intel Zepher 介绍
    使用IPMI发送事件1让BMC log 填满
    Knights Landing
    Intel历代处理器
    Intel Datacenter Group Public Roadmap
    django的url路由
    position用法
  • 原文地址:https://www.cnblogs.com/Abbey/p/2107898.html
Copyright © 2011-2022 走看看