• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 297,  comments - 15,  trackbacks - 0
            1.比較兩個字符串如果不等返回True?


            答案:
            Java代碼 
            package com.test.kaoshi;    
               
            public class StringDemo {    
               
                private static String a = "abc";    
                private static String b = "abcg";    
               
                public static boolean equalString() {    
                    if (a.equals(b)) {    
                        return false;    
                    } else {    
                            
                        return true;    
                    }    
                }    
                public static void main(String[] args) {    
                    StringDemo  sd = new StringDemo();    
                    System.out.println("主要考察返回Boolean變量和字符串比較使用的方法?+sd.equalString());    
                }    
            }   




            2.隨機產生20個字符并且排序?

            答案:
            Java代碼 
            package com.test.kaoshi;    
               
            import java.util.HashSet;    
            import java.util.Iterator;    
            import java.util.Random;    
            import java.util.Set;    
            import java.util.TreeSet;    
               
            public class RadomDemo {    
               
                public Set getChar(){    
                        
                    Set numberSet01 = new HashSet();    
                    Random rdm = new Random();    
                    char ch;    
                    while(numberSet01.size()<20){     
                       int rdGet = Math.abs(rdm.nextInt())%26+97;//產生97到122的隨機數a-z值    
                        ch=(char)rdGet;    
                        numberSet01.add(ch);    
                        //Set中是不能放進重復的值的,當它有20個時,就滿足你的條件了     
                    }     
                      return numberSet01;    
                    }    
                public static void main(String[] args) {    
                    RadomDemo rd = new RadomDemo();    
                    Set numberSet01=rd.getChar();    
                        
                    Set numberSet = new TreeSet();     
                    numberSet.addAll(numberSet01);    
                    for(Iterator it=numberSet01.iterator();it.hasNext();){     
                        System.out.print(it.next());     
                        }     
                    System.out.println();    
                    for(Iterator it=numberSet.iterator();it.hasNext();){     
                        System.out.print(it.next());     
                        }     
                }    
            }   



            3.50個人圍成一圈數到三和三的倍數時出圈,問剩下的人是誰?在原來的位置是多少?


            答案:

            Java代碼 
            package com.test.kaoshi;    
               
            import java.util.Iterator;    
            import java.util.LinkedList;    
               
            public class YouXi {    
                public static int removeNM(int n, int m) {    
                    LinkedList ll = new LinkedList();    
                    for (int i = 0; i < n; i++)    
                        ll.add(new Integer(i + 1));    
                    int removed = -1;    
                    while (ll.size() > 1) {    
                        removed = (removed + m) % ll.size();    
                        ll.remove(removed--);    
                    }    
                    return ((Integer) ll.get(0)).intValue();    
                }    
               
                public static void main(String[] args) {    
                    System.out.println(removeNM(50, 3));    
                }    
            }   

            . 時針分針重合幾次
            表面上有60個小格,每小格代表一分鐘,
            時針每分鐘走1/12小格,分針每分鐘走1小格,從第一次重合到第二次重合分針比時針多走一圈即60小格,所以
            60/(1-1/12)=720/11
            每隔720/11分才重合一次(而并不是每小時重合一次)

            1440里有22個720/11,如果說算上0點和24點,那也是重合23次而已,但我覺得0點應該算到前一天的24點頭上,所以每一天循環下來重合22次啊

            2. 找出字符串的最長不重復子串,輸出長度
            建一個256個單元的數組,每一個單元代表一個字符,數組中保存上次該字符上次出現的位置;
            依次讀入字符串,同時維護數組的值;
            如果遇到沖突了,就返回沖突字符中保存的位置,繼續第二步。也可以用hashmap保存已經出現的字符和字符的位置

            3. 說是有一個文本文件,大約有一萬行,每行一個詞,要求統計出其中最頻繁出
            現的前十個詞。
            先用哈希,統計每個詞出現的次數,然后在用在N個數中找出前K大個數的方法找出出現
            次數最多的前10個詞。

            4. 如題3,但是車次文件特別大,沒有辦法一次讀入內存。
            1) 直接排序,寫文件時,同時寫入字符串及其出現
            次數。
            2) 可以用哈希,比如先根據字符串的第一個字符將字符串換分為多個區域,每個區域的字符串寫到一個文件內,然后再用哈希+堆統計每個區域內前10個頻率最高的字符串,最后求出所有字符串中前10個頻率最高的字符串。

            5. 有一個整數n,將n分解成若干個整數之和,問如何分解能使這些數的乘積最大,輸出這個乘積m。例如:n=12
            (1)分解為1+1+1+…+1,12個1, m=1*1*1……*1=1
            (2)分解為2+2+…+2,6個2, m=64
            (3)分解為3+3+3+3,4個3, m=81
            (4)大于等于4時分解時只能分解為2和3,且2最多兩個
            f(n) = 3*f(n-3) n>4
            f(4) = 2*2
            f(3) = 3
            f(2) = 2分解為4+4+4,3個4, m=64

            6. 求數組n中出現次數超過一半的數
            把數組分成[n/2]組,則至少有一組包含重復的數,因為如果無重復數,則最多只有出現次數等于一半的數。算法如下:
            k<-n;
            while k>3 do
            把數組分成[k/2]組;
            for i=1 to [k/2] do
                if 組內2個數相同,則任取一個數留下;
                else 2個數同時扔掉;
            k<-剩下的數
            if k=3
                then 任取2個數進行比較;
                  if 兩個數不同,則2個數都扔掉
                   else 任取一個數
                if k=2 or 1 then 任取一數

            7. A文件中最多有n個正整數,而且每個數均小于n,n <=10的七次方。不會出現重復的數。
            要求對A文件中的數進行排序,可用內存為1M,磁盤可用空間足夠。
            不要把任何問題都往很復雜的算法上靠,最直接最簡單的解決問題才是工程師應有的素質,
            題目給的很有分寸:n個數,都小于n,兩兩不同,1M=10^6byte=10^7bit的內存,n <10^7
            思路:
            把1M內存看作是一個長度為10^7的位數組,每一位都初始化為0
            從頭掃描n個數,如果碰到i,就把位數組的第i個位置置為1,

            1M內存有點少, (1M = 8M bits), 可以代表8M整數,現在n <=10的七次方,你可以讀2遍文件,就可以完成排序了。第一次排n <8M得數, 第2遍排 8M <n <10的七次方的數。


            8. 有10億個雜亂無章的數,怎樣最快地求出其中前1000大的數。
            1) 建一個1000個數的堆,復雜度為N*(log1000)=10N
            2) 1.用每一個BIT標識一個整數的存在與否,這樣一個字節可以標識8個整數的存在與否,對于所有32位的整數,需要512Mb,所以開辟一個512Mb的字符數組A,初始全0
               2.依次讀取每個數n,將A[n>>3]設置為A[n>>3]|(1<<n%8),相當于將每個數的對應位設置為1
               3.在A中,從大到小讀取1000個值為1的數,就是最大的1000個數了。
            這樣讀文件就只需要1遍,在不考慮內存開銷的情況下,應該是速度最快的方法了。

            9. 一棵樹節點1, 2, 3, ... , n. 怎樣實現:
            先進行O(n)預處理,然后任給兩個節點,用O(1)判斷它們的父子關系
            dfs一遍,記錄每個結點的開始訪問時間Si和結束訪問時間Ei
            對于兩個節點i,j,若區間[Si,Ei]包含[Sj,Ej],則i是j的祖先。給每個節點哈夫曼編碼也行,但只適合一般的二叉樹,而實際問題未必是Binary的,所以編碼有局限性

            10. 給定一個二叉樹,求其中N(N>=2)個節點的最近公共祖先節點。每個節點只有左右孩
            子指
            針,沒有父指針。
            后序遞歸給每個節點打分,每個節點的分數=左分數+右分數+k,如果某孩子是給定節點則+1
            最深的得分為N的節點就是所求吧,細節上應該不用遞歸結束就可以得到這個節點

            11. 如何打印如下的螺旋隊列:
            21 22 。。。。
            20 7 8 9 10
            19 6 1 2 11
            18 5 4 3 12
            17 16 15 14 13

            #include <stdio.h>
            #define max(a,b) ((a)<(b)?(b):(a))
            #define abs(a) ((a)>0?(a):-(a))
            int foo(int x, int y)
            {
            int t = max(abs(x), abs(y));
            int u = t + t;
            int v = u - 1;
            v = v * v + u;
            if (x == -t)
                v += u + t - y;
            else if (y == -t)
                v += 3 * u + x - t;
            else if (y == t )
                v += t - x;
            else
                      v += y - t;
            return v;
            }
            int main()
            {
            int x, y;
            for (y=-2;y<=2;y++)
            {
                for (x=-2;x<=2;x++)
                  printf("%5d", foo(x, y));
                printf("\n");
            }
            return 0;
            }
            第 0 層規定為中間的那個 1,第 1 層為 2 到 9,第 2 層為 10 到 25,……好像看出一點名堂來了?注意到 1、9、25、……不就是平方數嗎?而且是連續奇數(1、3、5、……)的平方數。這些數還跟層數相關,推算一下就可以知道第 t 層之內一共有 (2t-1)^2 個數,因而第 t 層會從 [(2t-1)^2] + 1 開始繼續往外螺旋。給定坐標 (x,y),如何知道該點處于第幾層?so easy,層數 t = max(|x|,|y|)。

            知道了層數,接下來就好辦多了,這時我們就知道所求的那點一定在第 t 層這個圈上,順著往下數就是了。要注意的就是螺旋隊列數值增長方向和坐標軸正方向并不一定相同。我們可以分成四種情況——上、下、左、右——或者——東、南、西、北,分別處于四條邊上來分析。

            東|右:x == t,隊列增長方向和 y 軸一致,正東方向(y = 0)數值為 (2t-1)^2 + t,所以 v = (2t-1)^2 + t + y

            南|下:y == t,隊列增長方向和 x 軸相反,正南方向(x = 0)數值為 (2t-1)^2 + 3t,所以 v = (2t-1)^2 + 3t - x

            西|左:x == -t,隊列增長方向和 y 軸相反,正西方向(y = 0)數值為 (2t-1)^2 + 5t,所以 v = (2t-1)^2 + 5t - y

            北|上:y == -t,隊列增長方向和 x 軸一致,正北方向(x = 0)數值為 (2t-1)^2 + 7t,所以 v = (2t-1)^2 + 7t + x

            12. 一個整數,知道位數,如何判斷它是否能被3整除,不可以使用除法和模運算
            首先 3x=2^n+1時 僅當 n 為奇數才可能 因為2^n = 3x + (-1)^n;所以該問題就轉化為了
            找到最后一個為1的位a,看看向前的一個1(b)和這個位的距離,如果為偶數的距離則不能整除,如果是奇數,去除b之后的位繼續判斷

            13. seq=[a,b,...,z,aa,ab,...,az,ba,bb...,bz,...za,zb,...,zz,aaa...],求[a-z]+(從a到z任意字符組成的字符串)s在seq的位置,即排在第幾
            本質就是26進制。

            大家都知道,看一個數是否能被2整除只需要看它的個位能否被2整除即可。可是你想過為什么嗎?這是因為10能被2整除,因此一個數10a+b能被2整除當且僅當b能被2整除。大家也知道,看一個數能否被3整除只需要看各位數之和是否能被3整除。這又是為什么呢?答案或多或少有些類似:因為10^n-1總能被3整除。2345可以寫成2*(999+1) + 3*(99+1) + 4*(9+1) + 5,展開就是2*999+3*99+4*9 + 2+3+4+5。前面帶了數字9的項肯定都能被3整除了,于是要看2345能否被3整除就只需要看2+3+4+5能否被3整除了。當然,這種技巧只能在10進制下使用,不過類似的結論可以推廣到任意進制。
                 注意到36是4的整數倍,而ZZZ...ZZ除以7總是得555...55。也就是說,判斷一個36進制數能否被4整除只需要看它的個位,而一個36進制數能被7整除當且僅當各位數之和能被7整除。如果一個數同時能被4和7整除,那么這個數就一定能被28整除。于是問題轉化為,有多少個連續句子滿足各位數字和是7的倍數,同時最后一個數是4的倍數。這樣,我們得到了一個O(n)的算法:用P[i]表示前若干個句子除以7的余數為i有多少種情況,掃描整篇文章并不斷更新P數組。當某句話的最后一個字能被4整除時,假設以這句話結尾的前綴和除以7余x,則將此時P[x]的值累加到最后的輸出結果中(兩個前綴的數字和除以7余數相同,則較長的前綴多出來的部分一定整除7)。
                 上述算法是我出這道題的本意,但比賽后我見到了其它各種各樣新奇的算法。比如有人注意到36^n mod 28總是等于8,利用這個性質也可以構造出類似的線性算法來。還有人用動態規劃(或者說遞推)完美地解決了這個問題。我們用f[i,j]表示以句子i結束,除以28余數為j的文本片段有多少個;處理下一句話時我們需要對每一個不同的j進行一次掃描,把f[i-1,j]加進對應的f[i,j']中。最后輸出所有的f[i,0]的總和即可。這個動態規劃可以用滾動數組,因此它的空間同前面的算法一樣也是常數的。
                 如果你完全不知道我在說什么,你可以看看和進位制、同余相關的文章。另外,我之前還曾出過一道很類似的題(VOJ1090),你可以對比著看一看。

             

             
            有一個整數n,寫一個函數f(n),返回0到n之間出現的"1"的個數。比如f(13)=6,現在f(1)=1,問有哪些n能滿足f(n)=n?

            例如:f(13)=6, 因為1,2,3,4,5,6,7,8,9,10,11,12,13.數數1的個數,正好是6.

            public class Test {

            public int n = 2;

            public int count = 0;

            public void BigestNumber(int num) {

            for (int i = 1; i <= num; i++) {
            int m = 0;

            int j = i;
            while (j > 0) {
            m = j % 10;

            if (m == 1)
                count++;
            if (j > 0)
                j = j / 10;

            }

            }

            System.out.println("f(" + num + ")=" + count);


            }

            public static void main(String args[]) {
            Test t = new Test();
            long begin = System.currentTimeMillis();
            t.BigestNumber(10000000);
            long end = System.currentTimeMillis();
            System.out.println("總時間" + (end-begin)/1000 + "秒");
            }
            }


            結果:
            f(10000000)=7000001
            總時間5秒
             
             

            1、將一整數逆序后放入一數組中(要求遞歸實現)
            void convert(int *result, int n) {
             if(n>=10)
              convert(result+1, n/10);
             *result = n%10;
            }
            int main(int argc, char* argv[]) {
             int n = 123456789, result[20]={};
             convert(result, n);
             printf("%d:", n);
             for(int i=0; i<9; i++)
              printf("%d", result);
            }
            2、求高于平均分的學生學號及成績(學號和成績人工輸入)
            double find(int total, int n) {
             int number, score,  average;
             scanf("%d", &number);
             if(number != 0) {
              scanf("%d", &score);
              average = find(total+score, n+1);
              if(score >= average)
               printf("%d:%d\n", number, score);
              return average;
             } else {
              printf("Average=%d\n", total/n);
              return total/n;
             }
            }
            int main(int argc, char* argv[]) {
             find(0, 0);
            }
            3、遞歸實現回文判斷(如:abcdedbca就是回文,判斷一個面試者對遞歸理解的簡單程序)
            int find(char *str, int n) {
             if(n<=1) return 1;
             else if(str[0]==str[n-1]) return find(str+1, n-2);
             else  return 0;
            }
            int main(int argc, char* argv[]) {
             char *str = "abcdedcba";
             printf("%s: %s\n", str, find(str, strlen(str)) ? "Yes" : "No");
            }
            4、組合問題(從M個不同字符中任取N個字符的所有組合)
            void find(char *source, char *result, int n) {
             if(n==1) {
              while(*source)
                 printf("%s%c\n", result, *source++);
             } else {
              int i, j;
              for(i=0; source != 0; i++);
              for(j=0; result[j] != 0; j++);
              for(; i>=n; i--) {
               result[j] = *source++;
               result[j+1] = '\0';
               find(source, result, n-1);
              }
             }
            }
            int main(int argc, char* argv[]) {
             int const n = 3;
             char *source = "ABCDE", result[n+1] = {0};
             if(n>0 && strlen(source)>0 && n<=strlen(source))
              find(source, result, 3);
            }
            5、分解成質因數(如435234=251*17*17*3*2,據說是華為筆試題)
            void prim(int m, int n) {
             if(m>n) {
              while(m%n != 0) n++;
              m /= n;
              prim(m, n);
              printf("%d*", n);
             }
            }
            int main(int argc, char* argv[]) {
             int n = 435234;
             printf("%d=", n);
             prim(n, 2);
            }
            6、尋找迷宮的一條出路,o:通路; X:障礙。(大家經常談到的一個小算法題)
            #define MAX_SIZE  8
            int H[4] = {0, 1, 0, -1};
            int V[4] = {-1, 0, 1, 0};          
            char Maze[MAX_SIZE][MAX_SIZE] = {{'X','X','X','X','X','X','X','X'},
                                             {'o','o','o','o','o','X','X','X'},
                                             {'X','o','X','X','o','o','o','X'},
                                         {'X','o','X','X','o','X','X','o'},
                                     {'X','o','X','X','X','X','X','X'},
            {'X','o','X','X','o','o','o','X'},
                     {'X','o','o','o','o','X','o','o'},
                                             {'X','X','X','X','X','X','X','X'}};
            void FindPath(int X, int Y) {
                if(X == MAX_SIZE || Y == MAX_SIZE) {
                   for(int i = 0; i < MAX_SIZE; i++)
            for(int j = 0; j < MAX_SIZE; j++)
                              printf("%c%c", Maze[j], j < MAX_SIZE-1 ? ' ' : '\n');
            }else for(int k = 0; k < 4; k++)
            if(X >= 0 && Y >= 0 && Y < MAX_SIZE && X < MAX_SIZE && 'o' == Maze[X][Y]) {
                               Maze[X][Y] = ' ';
                               FindPath(X+V[k], Y+H[k]);
                               Maze[X][Y] ='o';
            }
            }
            int main(int argc, char* argv[]) {
                FindPath(1,0);
            }
            7、隨機分配座位,共50個學生,使學號相鄰的同學座位不能相鄰(早些時候用C#寫的,沒有用C改寫)。
            static void Main(string[] args)
            {
             int Tmp = 0, Count = 50;  
             int[] Seats = new int[Count];  
             bool[] Students = new bool[Count];
             System.Random RandStudent=new System.Random();
             Students[Seats[0]=RandStudent.Next(0,Count)]=true;
             for(int i = 1; i < Count; ) {
                 Tmp=(int)RandStudent.Next(0,Count);
                 if((!Students[Tmp])&&(Seats[i-1]-Tmp!=1) && (Seats[i-1] - Tmp) != -1) {
               Seats[i++] = Tmp;
            Students[Tmp] = true;
              }
             }
             foreach(int Student in Seats)
                 System.Console.Write(Student + " ");
             System.Console.Read();
            }
            8、求網格中的黑點分布?,F有6*7的網格,在某些格子中有黑點,已知各行與各列中有黑點的點數之和,請在這張網格中畫出黑點的位置。(這是一網友提出的題目,說是他筆試時遇到算法題)
            #define ROWS 6
            #define COLS 7
            int iPointsR[ROWS] = {2, 0, 4, 3, 4, 0};           // 各行黑點數和的情況
            int iPointsC[COLS] = {4, 1, 2, 2, 1, 2, 1};        // 各列黑點數和的情況
            int iCount, iFound;
            int iSumR[ROWS], iSumC[COLS], Grid[ROWS][COLS];
            int Set(int iRowNo) {
            if(iRowNo == ROWS) {
                    for(int iColNo=0; iColNo < COLS && iSumC[iColNo]==iPointsC[iColNo]; iColNo++)
                       if(iColNo == COLS-1) {
                           printf("\nNo.%d:\n", ++iCount);
                           for(int i=0; i < ROWS; i++)
                              for(int j=0; j < COLS; j++)
                                  printf("%d%c", Grid[j], (j+1) % COLS ? ' ' : '\n');
                           iFound = 1; // iFound = 1,有解
                       }
                } else {
                    for(int iColNo=0; iColNo < COLS; iColNo++) {
                        if(iPointsR[iRowNo] == 0) {
                            Set(iRowNo + 1);
               } else if(Grid[iRowNo][iColNo]==0) {
            Grid[iRowNo][iColNo] = 1;
            iSumR[iRowNo]++; iSumC[iColNo]++;                                  if(iSumR[iRowNo]<iPointsR[iRowNo] && iSumC[iColNo]<=iPointsC[iColNo])
                                 Set(iRowNo);
            else if(iSumR[iRowNo]==iPointsR[iRowNo] && iRowNo < ROWS)
                                 Set(iRowNo + 1);
                            Grid[iRowNo][iColNo] = 0;
                            iSumR[iRowNo]--;
            iSumC[iColNo]--;
                        }
                    }
                }
            return iFound;     // 用于判斷是否有解
            }
            int main(int argc, char* argv[]) {
                if(!Set(0))
                    printf("Failure!");
            }
            9、有4種面值的郵票很多枚,這4種郵票面值分別1, 4, 12, 21,現從多張中最多任取5張進行組合,求取出這些郵票的最大連續組合值。(據說是華為2003年校園招聘筆試題)
            #define N 5
            #define M 5
            int k, Found, Flag[N];
            int Stamp[M] = {0, 1, 4, 12, 21};
            // 在剩余張數n中組合出面值和Value
            int Combine(int n, int Value) {
             if(n >= 0 && Value == 0) {
              Found = 1;
              int Sum = 0;
              for(int i=0; i<N && Flag != 0; i++) {
               Sum += Stamp[Flag];
               printf("%d ", Stamp[Flag]);
              }
              printf("\tSum=%d\n\n", Sum);
             }else for(int i=1; i<M && !Found && n>0; i++)
              if(Value-Stamp >= 0) {
               Flag[k++] = i;
               Combine(n-1, Value-Stamp);
               Flag[--k] = 0;
              }
             return Found;
            }
            int main(int argc, char* argv[]) {
             for(int i=1; Combine(N, i); i++, Found=0);
            }
            10、大整數數相乘的問題。(這是2002年在一考研班上遇到的算法題)
            void Multiple(char A[], char B[], char C[]) {
                int TMP, In=0, LenA=-1, LenB=-1;
                while(A[++LenA] != '\0');
                while(B[++LenB] != '\0');
                int Index, Start = LenA + LenB - 1;
                for(int i=LenB-1; i>=0; i--) {
                    Index = Start--;
                    if(B != '0') {
                        for(int In=0, j=LenA-1; j>=0; j--) {
                            TMP = (C[Index]-'0') + (A[j]-'0') * (B - '0') + In;
                            C[Index--] = TMP % 10 + '0';
                            In = TMP / 10;
                        }
                        C[Index] = In + '0';
                    }
                }
            }
            int main(int argc, char* argv[]) {
                char A[] = "21839244444444448880088888889";
                char B[] = "38888888888899999999999999988";
            char C[sizeof(A) + sizeof(B) - 1];
                for(int k=0; k<sizeof(C); k++)
                    C[k] = '0';
                C[sizeof(C)-1] = '\0';
                Multiple(A, B, C);
                for(int i=0; C != '\0'; i++)
                    printf("%c", C);
            }
            11、求最大連續遞增數字串(如“ads3sl456789DF3456ld345AA”中的“456789”)
            int GetSubString(char *strSource, char *strResult) {
                int iTmp=0, iHead=0, iMax=0;
                for(int Index=0, iLen=0; strSource[Index]; Index++) {
                    if(strSource[Index] >= '0' && strSource[Index] <= '9' &&
            strSource[Index-1] > '0' && strSource[Index] == strSource[Index-1]+1) {
                        iLen++;                       // 連續數字的長度增1
                    } else {                          // 出現字符或不連續數字
                        if(iLen > iMax) {
                        iMax = iLen;  iHead = iTmp;
                        }       
                    // 該字符是數字,但數字不連續
                        if(strSource[Index] >= '0' && strSource[Index] <= '9') {
                            iTmp = Index;
            iLen = 1;
                        }
                    }   
                }
                for(iTmp=0 ; iTmp < iMax; iTmp++) // 將原字符串中最長的連續數字串賦值給結果串
                    strResult[iTmp] = strSource[iHead++];
                strResult[iTmp]='\0';
                return iMax;     // 返回連續數字的最大長度
            }
            int main(int argc, char* argv[]) {
                char strSource[]="ads3sl456789DF3456ld345AA", char strResult[sizeof(strSource)];
            printf("Len=%d, strResult=%s \nstrSource=%s\n",
            GetSubString(strSource, strResult), strResult, strSource);
            }
            12、四個工人,四個任務,每個人做不同的任務需要的時間不同,求任務分配的最優方案。(2005年5月29日全國計算機軟件資格水平考試——軟件設計師的算法題)。
            #include "stdafx.h"
            #define N 4
            int Cost[N][N] = { {2, 12, 5, 32},  // 行號:任務序號,列號:工人序號
                                {8, 15, 7, 11},  // 每行元素值表示這個任務由不同工人完成所需要的時間
                                {24, 18, 9, 6},
                                {21, 1, 8, 28}};
            int MinCost=1000;
            int Task[N], TempTask[N], Worker[N];
            void Assign(int k, int cost) {
             if(k == N) {
              MinCost = cost;
              for(int i=0; i<N; i++)
               TempTask = Task;
             } else {
              for(int i=0; i<N; i++) {
               if(Worker==0 && cost+Cost[k] < MinCost) { // 為提高效率而進行剪枝
                Worker = 1; Task[k] = i;
                Assign(k+1, cost+Cost[k]);
                Worker = 0; Task[k] = 0;
               }
              }
             }
            }
            int main(int argc, char* argv[]) {
             Assign(0, 0);
             printf("最佳方案總費用=%d\n", MinCost);
             for(int i=0; i<N; i++) 
              printf("\t任務%d由工人%d來做:%d\n", i, TempTask, Cost[TempTask]);
            }

             

            13、八皇后問題,輸出了所有情況,不過有些結果只是旋轉了90度而已。(回溯算法的典型例題,是數據結構書上算法的具體實現,大家都親自動手寫過這個程序嗎?)
            #define N 8
            int Board[N][N];
            int Valid(int i, int j) {  // 判斷下棋位置是否有效
             int k = 1;
             for(k=1; i>=k && j>=k;k++)
              if(Board[i-k][j-k]) return 0;
             for(k=1; i>=k;k++)
              if(Board[i-k][j])  return 0;
             for(k=1; i>=k && j+k<N;k++)
              if(Board[i-k][j+k]) return 0;
             return 1;
            }
            void Trial(int i, int n) {  // 尋找合適下棋位置
             if(i == n) {
              for(int k=0; k<n; k++) {
               for(int m=0; m<n; m++)
                printf("%d ", Board[k][m]);
               printf("\n");
              }
              printf("\n");
             } else {
              for(int j=0; j<n; j++) {
               Board[j] = 1;
               if(Valid(i,j))
                Trial(i+1, n);
               Board[j] = 0;
              }
             }
            }
            int main(int argc, char* argv[]) {
             Trial(0, N);
            }
            14、實現strstr功能,即在父串中尋找子串首次出現的位置。(筆試中常讓面試者實現標準庫中的一些函數)
            char * strstring(char *ParentString, char *SubString) {
             char *pSubString, *pPareString;
             for(char *pTmp=ParentString; *pTmp; pTmp++) {
              pSubString = SubString;
              pPareString = pTmp;
              while(*pSubString == *pPareString && *pSubString != '\0') {
               pSubString++;
               pPareString++;
              }
              if(*pSubString == '\0')  return pTmp;
             }
             return NULL;
            }
            int main(int argc, char* argv[]) {
             char *ParentString = "happy birthday to you!";
             char *SubString = "birthday";
             printf("%s",strstring(ParentString, SubString));
            }
            15、現在小明一家過一座橋,過橋的時候是黑夜,所以必須有燈?,F在小明過橋要1分,小明的弟弟要3分,小明的爸爸要6分,小明的媽媽要8分,小明的爺爺要12分。每次此橋最多可過兩人,而過橋的速度依過橋最慢者而定,而且燈在點燃后30分就會熄滅。問小明一家如何過橋時間最短?(原本是個小小智力題,據說是外企的面試題,在這里用程序來求解)
            #include "stdafx.h"
            #define N    5
            #define SIZE 64
            // 將人員編號:小明-0,弟弟-1,爸爸-2,媽媽-3,爺爺-4
            // 每個人的當前位置:0--在橋左邊, 1--在橋右邊
            int Position[N];   
            // 過橋臨時方案的數組下標; 臨時方案; 最小時間方案;
            int Index, TmpScheme[SIZE], Scheme[SIZE];  
            // 最小過橋時間總和,初始值100;每個人過橋所需要的時間
            int MinTime=100, Time[N]={1, 3, 6, 8, 12}; 
            // 尋找最佳過橋方案。Remnant:未過橋人數; CurTime:當前已用時間;
            // Direction:過橋方向,1--向右,0--向左
            void Find(int Remnant, int CurTime, int Direction) {
                if(Remnant == 0) {                               // 所有人已經過橋,更新最少時間及方案
                    MinTime=CurTime;
                    for(int i=0; i<SIZE && TmpScheme>=0; i++)
                        Scheme = TmpScheme;
                } else if(Direction == 1) {                        // 過橋方向向右,從橋左側選出兩人過橋
                    for(int i=0; i<N; i++)                   
                        if(Position == 0 && CurTime + Time < MinTime) {
                            TmpScheme[Index++] = i;
                            Position = 1;
                            for(int j=0; j<N; j++) {
                                int TmpMax = (Time > Time[j] ? Time : Time[j]);
                                if(Position[j] == 0 && CurTime + TmpMax < MinTime) {
                                    TmpScheme[Index++] = j;   
                                    Position[j] = 1;       
                                    Find(Remnant - 2, CurTime + TmpMax, !Direction);
                                    Position[j] = 0;       
                                    TmpScheme[--Index] = -1;
                                }
                            }
                            Position = 0;
                            TmpScheme[--Index] = -1;
                        }
                } else {        // 過橋方向向左,從橋右側選出一個人回來送燈
                    for(int j=0; j<N; j++) {
                        if(Position[j] == 1 && CurTime+Time[j] < MinTime) {
                            TmpScheme[Index++] = j;
                            Position[j] = 0;
                            Find(Remnant+1, CurTime+Time[j], !Direction);
                            Position[j] = 1;
                            TmpScheme[--Index] = -1;
                        }
                    }
                }
            }
            int main(int argc, char* argv[]) {
                for(int i=0; i<SIZE; i++)   // 初始方案內容為負值,避免和人員標號沖突
                    Scheme = TmpScheme = -1;
            Find(N, 0, 1);        // 查找最佳方案
                printf("MinTime=%d:", MinTime); // 輸出最佳方案
                for(int i=0; i<SIZE && Scheme>=0; i+=3)
                    printf("  %d-%d  %d", Scheme, Scheme[i+1], Scheme[i+2]);
                printf("\b\b  ");
            }
            16、2005年11月金山筆試題。編碼完成下面的處理函數。函數將字符串中的字符'*'移到串的前部分,前面的非'*'字符后移,但不能改變非'*'字符的先后順序,函數返回串中字符'*'的數量。如原始串為:ab**cd**e*12,處理后為*****abcde12,函數并返回值為5。(要求使用盡量少的時間和輔助空間)
            int change(char *str) {    
             int count = 0;    
             for(int i=0, j=0; str; i++) { 
              if(str=='*') {   
               for(j=i-1; str[j]!='*'&&j>=0; j--)
                str[j+1]=str[j];    
               str[j+1] = '*';
               count++;
              }
             }
             return count;
            }
            int main(int argc, char* argv[]) {
             char str[] = "ab**cd**e*12";
             printf("str1=%s\n", str);
             printf("str2=%s, count=%d", str, change(str));
            }
            // 終于得到一個比較高效的算法,一個網友提供,估計應該和金山面試官的想法一致。算法如下:
            int change(char *str) {
             int i,j=strlen(str)-1;
             for(i=j; j>=0; j--) {
              if(str!='*') {
               i--;
              } else if(str[j]!='*') {
               str = str[j];
               str[j] = '*';
               i--;
              }
             }
             return i+1;
            }
            17、2005年11月15日華為軟件研發筆試題。實現一單鏈表的逆轉。
            #include "stdafx.h"
            typedef char eleType;  // 定義鏈表中的數據類型
            typedef struct listnode  { // 定義單鏈表結構
             eleType data;
             struct listnode *next;
            }node;
            node *create(int n) {  // 創建單鏈表,n為節點個數
             node *p = (node *)malloc(sizeof(node));
             node *head = p;  head->data = 'A';
             for(int i='B'; i<'A'+n; i++) {   
              p = (p->next = (node *)malloc(sizeof(node)));
              p->data = i;
              p->next = NULL; 
             }
             return head;
            }
            void print(node *head) { // 按鏈表順序輸出鏈表中元素
             for(; head; head = head->next)
              printf("%c ", head->data);
             printf("\n");
            }
            node *reverse(node *head, node *pre) { // 逆轉單鏈表函數。這是筆試時需要寫的最主要函數
             node *p=head->next;
             head->next = pre;
             if(p) return reverse(p, head);
             else  return head;
            }
            int main(int argc, char* argv[]) {
             node *head = create(6);
             print(head);
             head = reverse(head, NULL);
             print(head);
            }
            18、編碼實現字符串轉整型的函數(實現函數atoi的功能),據說是神州數碼筆試題。如將字符串 ”+123”?123, ”-0123”?-123, “123CS45”?123, “123.45CS”?123, “CS123.45”?0
            #include "stdafx.h"
            int str2int(const char *str) {    // 字符串轉整型函數
             int i=0, sign=1, value = 0;
             if(str==NULL)  return NULL;    // 空串直接返回 NULL
             if(str[0]=='-' || str[0]=='+') {   // 判斷是否存在符號位
              i = 1;
              sign = (str[0]=='-' ? -1 : 1);
             }
             for(; str>='0' && str<='9'; i++) // 如果是數字,則繼續轉換
              value = value * 10 + (str - '0');
             return sign * value;
            }
            int main(int argc, char *argv[]) {
             char *str = "-123.45CS67";
             int  val  = str2int(str);
             printf("str=%s\tval=%d\n", str, val);
            }
            19、歌德巴赫猜想。任何一個偶數都可以分解為兩個素數之和。(其實這是個C二級考試的模擬試題)
            #include "stdafx.h"
            #include "math.h"
            int main(int argc, char* argv[]) {
             int Even=78, Prime1, Prime2, Tmp1, Tmp2;
             for(Prime1=3; Prime1<=Even/2; Prime1+=2) {
              for(Tmp1=2,Tmp2=sqrt(float(Prime1)); Tmp1<=Tmp2 && Prime1%Tmp1 != 0; Tmp1++);
              if(Tmp1<=Tmp2) continue;
              Prime2 = Even-Prime1;
              for(Tmp1=2,Tmp2=sqrt(float(Prime2)); Tmp1<=Tmp2 && Prime2%Tmp1 != 0; Tmp1++);
              if(Tmp1<=Tmp2) continue;
              printf("%d=%d+%d\n", Even, Prime1, Prime2);
             }
            }
            20、快速排序(東軟喜歡考類似的算法填空題,又如堆排序的算法等)
            #include "stdafx.h"
            #define N 10
            int part(int list[], int low, int high) {  // 一趟排序,返回分割點位置
             int tmp = list[low];
             while(low<high) {
              while(low<high && list[high]>=tmp) --high;
              list[low] = list[high];
              while(low<high && list[low]<=tmp)  ++low;
              list[high] = list[low];
             }
             list[low] = tmp;
             return low;
            }
            void QSort(int list[], int low, int high) { // 應用遞歸進行快速排序
             if(low<high) {
              int mid = part(list, low, high);
              QSort(list, low, mid-1);
              QSort(list, mid+1, high);
             }
            }
            void show(int list[], int n) {    // 輸出列表中元素
             for(int i=0; i<n; i++)
              printf("%d ", list);
             printf("\n");
            }
            int main(int argc, char* argv[]) {
             int list[N] = {23, 65, 26, 1, 6, 89, 3, 12, 33, 8};
             show(list, N);      // 輸出排序前序列
             QSort(list, 0, N-1);     // 快速排序
             show(list, N);      // 輸出排序后序列
            }
            21、2005年11月23日慧通筆試題:寫一函數判斷某個整數是否為回文數,如12321為回文數。可以用判斷入棧和出棧是否相同來實現(略微復雜些),這里是將整數逆序后形成另一整數,判斷兩個整數是否相等來實現的。
            #include "stdafx.h"
            int IsEchoNum(int num) {
             int tmp = 0;
             for(int n = num; n; n/=10)
              tmp = tmp *10 + n%10;
             return tmp==num;
            }
            int main(int argc, char* argv[]) {
             int num = 12321;
             printf("%d  %d\n", num, IsEchoNum(num));
            }
            22、刪除字符串中的數字并壓縮字符串(神州數碼以前筆試題),如字符串”abc123de4fg56”處理后變為”abcdefg”。注意空間和效率。(下面的算法只需要一次遍歷,不需要開辟新空間,時間復雜度為O(N))
            #include "stdafx.h"
            void delNum(char *str) {
             int i, j=0;
            // 找到串中第一個數字的位子
             for(i=j=0; str && (str<'0' || str>'9'); j=++i);
             
             // 從串中第一個數字的位置開始,逐個放入后面的非數字字符
             for(; str; i++)  
              if(str<'0' || str>'9')
               str[j++] = str;
             str[j] = '\0';
            }
            int main(int argc, char* argv[]) {
             char str[] = "abc123ef4g4h5";
             printf("%s\n", str);
             delNum(str);
             printf("%s\n", str);
            }
            23、求兩個串中的第一個最長子串(神州數碼以前試題)。如"abractyeyt","dgdsaeactyey"的最大子串為"actyet"。
            #include "stdafx.h"
            char *MaxSubString(char *str1, char *str2) {
             int i, j, k, index, max=0;
             for(i=0; str1; i++)
              for(j=0; str2[j]; j++) {
               for(k=0; str1[i+k]==str2[j+k] && (str2[i+k] || str1[i+k]); k++);
               if(k>max) {  // 出現大于當前子串長度的子串,則替換子串位置和程度
                index = j; max = k;
               }
              }
             char *strResult = (char *)calloc(sizeof(char), max+1);
             for(i=0; i<max; i++) 
              strResult = str2[index++];
             return strResult;
            }
            int main(int argc, char* argv[]) {
             char str1[] = "abractyeyt", str2[] = "dgdsaeactyey";
             char *strResult = MaxSubString(str1, str2);
             printf("str1=%s\nstr2=%s\nMaxSubString=%s\n", str1, str2, strResult);
            }
            24、不開辟用于交換數據的臨時空間,如何完成字符串的逆序(在技術一輪面試中,有些面試官會這樣問)
            #include "stdafx.h"
            void change(char *str) {
             for(int i=0,j=strlen(str)-1; i<j; i++, j--){
              str ^= str[j] ^= str ^= str[j];
             }
            }
            int main(int argc, char* argv[]) {
             char str[] = "abcdefg";
             printf("strSource=%s\n", str);
             change(str);
             printf("strResult=%s\n", str);
             return getchar();
            }
            25、刪除串中指定的字符(做此題時,千萬不要開辟新空間,否則面試官可能認為你不適合做嵌入式開發)
            #include "stdafx.h"
            void delChar(char *str, char c) {
             int i, j=0;
             for(i=0; str; i++)
              if(str!=c) str[j++]=str;
             str[j] = '\0';
            }
            int main(int argc, char* argv[]) {
             char str[] = "abcdefgh"; // 注意,此處不能寫成char *str = "abcdefgh";
             printf("%s\n", str);
             delChar(str, 'c');
             printf("%s\n", str);
            }
            26、判斷單鏈表中是否存在環(網上說的筆試題)
            #include "stdafx.h"
            typedef char eleType;    // 定義鏈表中的數據類型
            typedef struct listnode  {   // 定義單鏈表結構
             eleType data;
             struct listnode *next;
            }node;
            node *create(int n) {    // 創建單鏈表,n為節點個數
             node *p = (node *)malloc(sizeof(node));
             node *head = p;  head->data = 'A';
             for(int i='B'; i<'A'+n; i++) {
              p = (p->next = (node *)malloc(sizeof(node)));
              p->data = i;
              p->next = NULL;
             }
             return head;
            }
            void addCircle(node *head, int n) { // 增加環,將鏈尾指向鏈中第n個節點
             node *q, *p = head;
             for(int i=1; p->next; i++) {
              if(i==n) q = p;
              p = p->next;
             }
             p->next = q;
            }
            int isCircle(node *head) {   // 這是筆試時需要寫的最主要函數,其他函數可以不寫
             node *p=head,*q=head;
             while( p->next && q->next) {
              p = p->next;
              if (NULL == (q=q->next->next)) return 0;
              if (p == q) return 1;
             }
             return 0;
            }
            int main(int argc, char* argv[]) {
             node *head = create(12);
             addCircle(head, 8);   // 注釋掉此行,連表就沒有環了
             printf("%d\n", isCircle(head));
            }
            from:
            http://blog.chinaunix.net/u2/67780/showart.php?id=2077586

            posted on 2009-11-16 12:18 chatler 閱讀(3389) 評論(0)  編輯 收藏 引用 所屬分類: Algorithm
            <2010年1月>
            272829303112
            3456789
            10111213141516
            17181920212223
            24252627282930
            31123456

            常用鏈接

            留言簿(10)

            隨筆分類(307)

            隨筆檔案(297)

            algorithm

            Books_Free_Online

            C++

            database

            Linux

            Linux shell

            linux socket

            misce

            • cloudward
            • 感覺這個博客還是不錯,雖然做的東西和我不大相關,覺得看看還是有好處的

            network

            OSS

            • Google Android
            • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
            • os161 file list

            overall

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            国产精品一区二区久久| 久久久久亚洲AV无码专区桃色| 久久av高潮av无码av喷吹| 色欲综合久久中文字幕网| 伊人久久大香线蕉av一区| 亚洲国产成人精品无码久久久久久综合 | 99久久无色码中文字幕人妻| 久久无码精品一区二区三区| 久久国产高清一区二区三区| 亚洲国产成人久久一区久久| 伊人久久大香线蕉AV一区二区| 亚洲精品NV久久久久久久久久 | 国产韩国精品一区二区三区久久| 亚洲精品国产字幕久久不卡| 久久婷婷成人综合色综合| 97热久久免费频精品99| 久久夜色精品国产亚洲| 久久国产精品二国产精品| 亚洲欧美成人久久综合中文网| av色综合久久天堂av色综合在| 久久精品水蜜桃av综合天堂| 久久精品国产秦先生| 久久精品中文字幕一区| 亚洲婷婷国产精品电影人久久| 人妻精品久久久久中文字幕69| segui久久国产精品| 久久久久久av无码免费看大片| 久久国语露脸国产精品电影| 久久久久久国产精品免费无码| 国产精品久久久99| 久久国产劲爆AV内射—百度| 99精品伊人久久久大香线蕉| 久久人人爽人人人人爽AV| 国产精品天天影视久久综合网| 久久久无码精品午夜| 久久久久亚洲AV无码专区体验| 久久精品国产99久久久香蕉| 久久综合狠狠综合久久| 伊人久久亚洲综合影院| 国内精品久久久久久久亚洲| 久久婷婷五月综合国产尤物app|