旋轉向量方法的一些學習

最近也沒閒着,上次學習了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,這麼說吧,旋轉速度未知,反正是很快,但是初始化時間,實在是太長了了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章