旋转向量方法的一些学习

来源:互联网 发布:美津浓跑鞋矩阵 编辑:程序博客网 时间:2024/06/02 10:24

最近也没闲着,上次学习了SuperSort之后,(书上好像叫做“位图方法”),顺便去复习了一下常规的排序算法,现在基本上都过了一遍,代码也差不多写完了,准备再整理整理过两天发上来,其实有这么写博客挺好的,写下来以后就不用在去自己的电脑里找了,而且写博客的过程也是对知识的一个提炼和复习,当然,还是那句话,本人菜鸟,欢迎拍砖,争取早日实现博客评论的零记录。

好,言归正传:

给定一个字符串诸如“abcdefg”,然后要求向左移动三位,即得到“defgabc”这样的结果,当然前提是不使用现成的方法,而且书中还要求是只能额外使用少量的内存空间,(只有1位?)

下面是用的想当然的办法应该是最差的了吧

        static void change(List<char> list, int n)
        {
            char temp;
            int count = list.Count;
            for (int i = 0; i < n; i++)
            {
                temp = list[0];
                for (int j = 0; j < count-1; j++)
                {
                    list[j] = list[j + 1];
                }
                list[count-1] = temp;
            }
        }

而书上讲了这样一种办法,一共需要移动n位的话,

1.先将x[0]赋给temp,将x[n]赋给x[0],x[2n]赋给x[n],x[3n]赋给x[2n],然后再将x[0]赋给最后一个x[in]

2.再依此方法处理x[1],x[n+1],x[2n+1]...

....

n.直至x[n-1],x[2n-1]....

书中的介绍戛然而止,可是我试着敲代码的时候发现,最后的结果不是想要的结果,就拿第一步来说吧,x[0]最后到达的位置位x[in],而其实,x[0]最后到达的位置应该是x[count-n],(最后一位是count-1),所以我使用了迭代的方法,在这么处理一遍之后重新执行类似的操作

具体可以看下面的代码:

        static void change(int start, List<char> list,int n)
        {
            int count = list.Count;
            char temp =' ';
            int k;
            for (int i = 0; i < n; i++)
            {
                k = i + start;
                while (k < count)
                {
                    if (k < n + start)
                    {
                        temp = list[k];
                    }
                    else
                    {
                        list[k-n] = list[k];
                    }
                    k += n;
                }
                list[k - n] = temp;
            }
            if (count % n != 0)
            {
                change(count - n, list, n - (count-start) % n);
            }
        }

 

然后分别调用这两种方法

        static void Main(string[] args)
        {
            List<char> list1 = new List<char>();

            List<char> list2 = new List<char>();
           //StopWatch是秒表类,用于计时,具体可以看我前一篇博文《专为手机号码设计的特殊的排序[我的代码]》

            StopWatch sw1 = new StopWatch();
            StopWatch sw2 = new StopWatch();
            Random r = new Random();
            int j;
            for (int i = 0; i <1000000; i++)
            {
                j = r.Next(97, 122);
                list1.Add((char)j);
                list2.Add((char)j);
            }
            sw1.setStart();
            change(0,list1,7);
            sw1.setEnd();


            sw2.setStart();
            change(list2, 7);
            sw2.setEnd();
            Console.WriteLine();
            Console.WriteLine("time with the 1st change:" + sw1.getTime());
            Console.WriteLine("time with the 2nd change:" + sw2.getTime());
            Console.ReadLine();
        }

结果如下:(2nd用的是第一种方法,1st是书上的方法,图中是自己敲代码时候的顺序)

显而易见,后一种方法的速度更快,因为它减少了一些不必要的移位,不过始终觉得如果使用string型,然后再使用

            string s = list3.Substring(n);
            s += list3.Substring(0, n);

这样的方法,是不是速度更加快一点

我也试了一下,string型的初始化比较慢,速度过会儿写上,还在运行中。。。

我用的是这样的方法进行初始化的,list3是string型的,num我用的还是1000,000

            for (int i = 0; i < num; i++)
            {
                j = r.Next(97, 122);
                list3 += (char)j;
            }

我开始为我的cpu担心,顺便说一下,我的cpu是T5470,凭直觉,初始化时间是10分钟左右,希望能在我今天睡觉的时候完成。。。(刚才看了一下,还好,cpu温度保持在50摄氏度一下)另外我发现百度输入法看上去比较简介,界面很“清淡”,但是和Sogou比确实字库比较少,启动比较慢,假死比较多。。。

另外一个但是是希望string不要越界,查了一下String的最大长度=2的28次方 -1=268,435,455,应该没啥问题

string的+方法效率确实不咋地。。

(1st书中介绍的方法,2nd最简单的方法,3st,string的方法)

结果如下

3st用的就是string,这么说吧,旋转速度未知,反正是很快,但是初始化时间,实在是太长了了

原创粉丝点击