每週算法(一)

每週算法html

ios

     很高興每週算法專題終於能夠和你們見面,每週算法專題一週更新一次,每次五個算法,算法有難有易,算法均來源於各類經典的算法題以及各大公司招聘時的筆試面試題,咱們的目標在於算法的探討,尋找更好的解決方案,儘可能作到每個算法都給出從易到難的解題過程,從而使本身磨練出一套解決問題的思路,以及遇到新問題時該如何尋找解決方法。面試

     在此給出了本週相應的算法以及源碼,視屏教程能夠到此觀看算法

     http://edu.51cto.com/course/course_id-5071.html 編程


一、 最大公約數數組

<1> 題目描述:求解兩個整數(不能是負數)的最大公約數(要求兩數不能同時爲0)ide

<2> 方法一:窮舉法函數

<3> 方法二:相減法spa

<4> 方法三:歐幾里德展轉相除法htm

<5> 方法四:歐幾里德展轉相除法 遞歸實現

 

二、 最小公倍數

<1> 題目描述:求解兩個整數(不能是負數)的最小公倍數

<2> 方法一:窮舉法

<3> 方法二:公式lcm = a * b / gcd(a,b)

 

三、 二進制中1的個數<本題感謝 編程之美 的提供>

<1> 題目描述:對一個字節的無符號×××變量,求二進制數中1的個數

(要求:執行效率儘量高)

  <2> 方法一:使用模方法

  <3> 方法二:使用位操做運算

  <4> 方法三:時間複雜度是與1的個數有關的算法

  <5> 方法四:分支法

  <6> 方法五:查表法

 

四、 高效進制轉換

<1> 題目描述:對一個 unsigned long 的整數,將其轉換爲對應的16進制數

<2> 方法一:使用數組存儲數據

<3> 方法二:使用棧存儲數據

<4> 方法三:使用字符串常量高效轉換

 

五、 位設置(bit_set

<1> 題目描述: 對一個unsigned char 8 bit數據的指定位置0或置1操做,並保持其餘位不變。

       函數原型:voidbit_set(unsigned char *p_data, unsigned char position, bool flag);

     參數說明:p_data 是指定的原數據,position是指定位(取值範圍1~8),flag表示是置0仍是置1操做

<2> 方法一:分支設置法

<3> 方法二:位操做設置法

 

 

 

 

源碼:

1、最大公約數

一、 窮舉法

#include<iostream>

using namespacestd;

unsigned longGCD(unsigned long a, unsigned long b)

{

       if(a == 0)

              return b;

       else if(b == 0)

              return a;

    else if(a == b)

              return a;

       unsigned long gcd;

       gcd = a>b?b:a;

       while(gcd > 1)

       {

              if((a%gcd==0) &&(b%gcd==0))

                     return gcd;

              gcd--;

       }

       return gcd;

}

void main()

{

       unsigned long a,b;

       cout<<"請輸入a b:>";

       cin>>a>>b;

       unsigned long gcd = GCD(a,b);

       cout<<"gcd ="<<gcd<<endl;

}

 

二、 相減法

#include<iostream>

using namespacestd;

unsigned longGCD(unsigned long a, unsigned long b)

{

       if(a == 0)

              return b;

       else if(b == 0)

              return a;

    else if(a == b)

              return a;

       unsigned long gcd;

       while(a != b)

       {

              gcd = a > b ? (a-=b) : (b-=a);

       }

       return gcd;

}

void main()

{

       unsigned long a,b;

       cout<<"請輸入a b:>";

       cin>>a>>b;

       unsigned long gcd = GCD(a,b);

       cout<<"gcd ="<<gcd<<endl;

}

三、 歐幾里德展轉相除法

#include<iostream>

using namespacestd;

unsigned longGCD(unsigned long a, unsigned long b)

{

       if(a == 0)

              return b;

       else if(b == 0)

              return a;

    else if(a == b)

              return a;

       unsigned long mod = a % b;

       while(mod != 0)

       {

              a = b;

              b = mod;

              mod = a % b;

       }

       return b;

}

void main()

{

       unsigned long a,b;

       cout<<"請輸入a b:>";

       cin>>a>>b;

       unsigned long gcd = GCD(a,b);

       cout<<"gcd ="<<gcd<<endl;

}

四、 歐幾里德展轉相除法 遞歸實現

#include<iostream>

using namespacestd;

unsigned longGCD(unsigned long a, unsigned long b)

{

       if(b == 0)

              return a;

       else

              return GCD(b, a%b);

}

void main()

{

       unsigned long a,b;

       cout<<"請輸入a b:>";

       cin>>a>>b;

       unsigned long gcd = GCD(a,b);

       cout<<"gcd ="<<gcd<<endl;

}

 

2、最小公倍數

一、 窮舉法

#include<iostream>

using namespacestd;

unsigned longLCM(unsigned long a, unsigned long b)

{

       if(a * b == 0)

              return 0;

       unsigned long lcm = a > b ? a : b;

       while(1)

       {

              if((lcm%a==0) &&(lcm%b==0))

                     break;           

              lcm++;

       }

       return lcm;

}

 

void main()

{

       unsigned long a,b;

       cout<<"請輸入a b:>";

       cin>>a>>b;

 

       unsigned long lcm = LCM(a,b);

       cout<<"lcm ="<<lcm<<endl;

}

2、公式lcm = a * b / gcd(a,b)

#include<iostream>

using namespacestd;

unsigned longGCD(unsigned long a, unsigned long b)

{

       if(b == 0)

              return a;

       else

              return GCD(b, a%b);

}

unsigned longLCM(unsigned long a, unsigned long b)

{

       if(a * b == 0)

              return 0;

       return (a*b)/GCD(a,b);

}

 

void main()

{

       unsigned long a,b;

       cout<<"請輸入a b:>";

       cin>>a>>b;

 

       unsigned long lcm = LCM(a,b);

       cout<<"lcm ="<<lcm<<endl;

}

 

3、二進制中1的個數

1、使用模方法

#include<iostream>

using namespacestd;

intCount(unsigned char v)

{

       int count = 0;

       while(v != 0)

       {

              if(v % 2 == 1)

                     count++;

              v /= 2;

       }

       return count;

}

void main()

{

       unsigned char ch = 255;

       int count = Count(ch);

       cout<<"count ="<<count<<endl;

}

二、 使用位操做運算

#include<iostream>

using namespacestd;

intCount(unsigned char v)

{

       int count = 0;

       while(v != 0)

       {

              count += v & 0x01;

              v >>= 1;

       }

       return count;

}

void main()

{

       unsigned char ch = 255;

       int count = Count(ch);

       cout<<"count ="<<count<<endl;

}

三、 時間複雜度是與1的個數有關的算法

#include<iostream>

using namespacestd;

intCount(unsigned char v)

{

       int count = 0;

       while(v != 0)

       {

              v &= (v-1);

              count++;

       }

       return count;

}

 

void main()

{

       unsigned char ch = 255;

       int count = Count(ch);

       cout<<"count ="<<count<<endl;

}

四、 分支法

#include<iostream>

using namespacestd;

intCount(unsigned char v)

{

     int count = 0;

     switch (v)

     {

          case 0x0:

               count = 0;

               break;

          case 0x1:

          case 0x2:

          case 0x4:

          case 0x8:

          case 0x10:

          case 0x20:

          case 0x40:

          case 0x80:

               count = 1;

               break;

          case 0x3:

          case 0x6:

          case 0xc:

          case 0x18:

          case 0x30:

          case 0x60:

          case 0xc0:

               count = 2;

               break;

               //...

         // [注意] 此處須要把代碼補齊

      }

      return count;    

}

void main()

{

       unsigned char ch = 255;

       int count = Count(ch);

       cout<<"count ="<<count<<endl;

}

五、 查表法

#include<iostream>

using namespacestd;

intcountTable[256] =

{

     0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3,3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3,

        3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3,4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3,

        4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4,

        3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3,4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3,

        4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4,4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6,

        6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3,4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4,

        5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4,3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,

        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5,6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3,

        4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5,5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4,

        4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6,7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6,

        7, 6, 7, 7, 8

};

intCount(unsigned char v)

{

     return countTable[v];

}

void main()

{

       unsigned char ch = 255;

       int count = Count(ch);

       cout<<"count ="<<count<<endl;

}

 

4、進制轉換

一、 使用數組存儲數據

#include<iostream>

using namespacestd;

char*Convert_16(unsigned long value)

{

       static char Buffer[sizeof(unsignedlong)*2+1];

       int mod;

       for(int i=sizeof(unsigned long)*2-1;i>=0; --i)

       {

              mod = value % 16;

              if(mod < 10)

              {

                     Buffer[i] = mod + '0';

              }

              else

              {

                     Buffer[i] = (mod-10) + 'A';

              }

              value /= 16;

       }

       return Buffer;

}

void main()

{

       unsigned long value = 4711;

       char *result = Convert_16(value);

       cout<<value<<" ="<<"0x"<<result<<endl;

}

二、 使用棧存儲數據

#include<iostream>

#include<stack>

using namespacestd;

voidConvert_16(unsigned long value)

{

       stack<char> st;

       int mod;

       while(value != 0)

       {

              mod = value % 16;

              if(mod < 10)

              {

                     st.push(mod+'0');

              }

              else

              {

                     st.push((mod-10) + 'A');

              }

              value /= 16;

       }

       cout<<value<<" ="<<"0x";

       while(!st.empty())

       {

              cout<<st.top();

              st.pop();

       }

       cout<<endl;

}

void main()

{

       unsigned long value = 4711;

       Convert_16(value);

}

3、使用字符串常量高效轉換

#include<iostream>

#include<stack>

using namespacestd;

char*Convert_16(unsigned long value)

{

       static char Buffer[sizeof(unsignedlong)*2+1];

       for(int i=sizeof(unsigned long)*2-1;i>=0; --i)

       {

              Buffer[i] ="0123456789ABCDEF"[value%16];

              value /= 16;

       }

       return Buffer;

}

void main()

{

       unsigned long value = 4711;

       char *result = Convert_16(value);

       cout<<value<<" ="<<"0x"<<result<<endl;

}

 

5、位設置(bit_set

1、分支設置法

#include<iostream>

using namespacestd;

voidbit_set(unsigned char *p_data, unsigned char position, bool flag)

{

      if(flag)//1

       {

              switch(position)

              {

              case 1:

                     *p_data |= 0x01;

                     break;

              case 2:

                     *p_data |= 0x02;

                     break;

              case 3:

                     *p_data |= 0x04;

                     break;

              case 4:

                     *p_data |= 0x04;

                     break;

              case 5:

                     *p_data |= 0x05;

                     break;

              case 6:

                     *p_data |= 0x06;

                     break;

              case 7:

                     *p_data |= 0x07;

                     break;

              case 8:

                     *p_data |= 0x08;

                     break;

              }

       }

       else //0

       {

              switch(position)

              {

              case 1:

                     *p_data &= 0x01;

                     break;

              case 2:

                     *p_data &= 0x02;

                     break;

              case 3:

                     *p_data &= 0x03;

                     break;

              case 4:

                     *p_data &= 0x04;

                     break;

              case 5:

                     *p_data &= 0x05;

                     break;

              case 6:

                     *p_data &= 0x06;

                     break;

              case 7:

                     *p_data &= 0x07;

                     break;

              case 8:

                     *p_data &= 0x08;

                     break;

              }

       }

}

void main()

{

       bool flag = true;

       //bool flag = false;

       unsigned char data = 'A';

       unsigned char position = 3;

       bit_set(&data,position,flag);

       cout<<data<<endl;

}

 

二、 位操做設置法

#include<iostream>

using namespacestd;

voidbit_set(unsigned char *p_data, unsigned char position, bool flag)

{

       unsigned char v = 0x01;

      if(flag)//1

       {

              *p_data |= (v<<(position-1));

       }

       else //0

       {

              *p_data &= ~(v<<(position-1));

       }

}

void main()

{

       bool flag = true;

       //bool flag = false;

       unsigned char data = 'A';

       unsigned char position = 3;

       bit_set(&data,position,flag);

       cout<<data<<endl;

}

相關文章
相關標籤/搜索