欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
一些C語(yǔ)言中字符串的算法問(wèn)題解決實(shí)例小結

  http://www.jb51.net/article/80975.htm

2016

這篇文章主要介紹了一些C語(yǔ)言中字符串的算法問(wèn)題解決實(shí)例小結,包括將字符串轉化為int類(lèi)型的數及旋轉字符串等操作,需要的朋友可以參考下

  字符串問(wèn)題是面試中經(jīng)常出現的問(wèn)題,這類(lèi)問(wèn)題有很多,難以不一。下面是幾道字符串的題目,網(wǎng)上都能找到解答,自己實(shí)現了一下,供網(wǎng)友參考。感覺(jué)算法重要的是要有正確的思路,實(shí)現起來(lái)不是問(wèn)題。自己一定要多思考,這樣收獲可能會(huì )更多一點(diǎn)。
       
問(wèn)題1:找兩個(gè)字符串的最長(cháng)公共子串。
        具體描述,如果字符串一的所有字符按其在字符串中的順序出現在另外一個(gè)字符串二中,則字符串一稱(chēng)之為字符串二的子串。注意,并不要求子串(字符串一)的字符必須連續出現在字符串二中。請編寫(xiě)一個(gè)函數,輸入兩個(gè)字符串,求它們的最長(cháng)公共子串,并打印出最長(cháng)公共子串。
    思路:算法書(shū)上一般都有介紹,就是用動(dòng)態(tài)規劃的思想。關(guān)鍵是要找到最優(yōu)子結構性質(zhì),這一點(diǎn)比較難。另外一個(gè)經(jīng)常問(wèn)到的問(wèn)題“求子數組的最大和”,用的也是動(dòng)態(tài)規劃的思想。找兩個(gè)字符串最長(cháng)公共子串的核心就是找最優(yōu)子結構。
        設序列X = {x1,x2,…xm}和Y = {y1,y2,…yn}的最長(cháng)公共子串為Z = {z1,z2,…zk},則
        1 若xm= yn且zk=xm=yn, 則Zk-1是Xm-1和Yn-1的最長(cháng)公共子串
        2 若xm!=yn且zk!=xm,則Z是Xm-1和Y的最長(cháng)公共子串
        3 若xm!=yn且zk!=yn,則Z是X和Yn-1的最長(cháng)公共子串
         其中Xm-1= {x1,x2,…,xm-1},Yn-1 = {y1,y2,…,yn-1}Zk-1 = {z1,z2,…zk-1}
      有了上述關(guān)系,則很容易得到遞推的式子。用一個(gè)二維數組 R 記錄結果,其中Z[i][j]表示Xi和Yj的最長(cháng)公共子串長(cháng)度。
     (1)如果i = 0或j = 0,Z[i][j] = 0
     (2)如果xi和yj相等,Z[i][j] = Z[i-1][j-1] + 1
     (3) 如果xi和yj不相等,Z[i][j] = max{Z[i-1][j],Z[i][j-1]}
        基本上差不多了,但是題目要求打印最長(cháng)公共子串,只要用一個(gè)數組R記錄得到最長(cháng)公共子串的過(guò)程,其中R[i][j]表示Z[i][j]的值是由哪個(gè)子問(wèn)題的解得到的。
       參考代碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//函數功能 : 打印最長(cháng)公共子串
//函數參數 : X為源字符串1,Y為源字符串2,R為記錄的過(guò)程,row為R的行坐標,col為R的列坐標
//返回值 :  空
void LCS_Print(const char *X, const char *Y, int **R, int row, int col)
{
  if(R[row][col] == 1)
  {
    LCS_Print(X, Y, R, row-1, col-1);
    cout<<X[row-1];  //由Xi-1和Yj-1,再加上Xi或Yj得到
  }
  else if(R[row][col] == 2)
    LCS_Print(X, Y, R, row-1, col); //由Xi-1和Yj得到
  else if(R[row][col] == 3) 
    LCS_Print(X, Y, R, row, col-1); //由Xi和Yj-1得到
  else
    return;
}
//函數功能 : 求兩個(gè)字符串的最大公共子串
//函數參數 : X為源字符串1,Y為源字符串2
//返回值 :  最大長(cháng)度
int LCS(const char *X,const char *Y)
{
  if(X == NULL || Y == NULL)
    return 0;
  
  int lenX = strlen(X);
  int lenY = strlen(Y);
  if(lenX == 0 || lenY == 0)
    return 0;
  
  int i, j;
  int **C = new int *[lenX+1];
  int **R = new int *[lenX+1];
  
  //初始化
  for(i = 0; i <= lenX; i++)
  {
    C[i] = new int [lenY+1];
    R[i] = new int [lenY+1];
    for(j = 0; j <= lenY; j++)
    {
      C[i][j] = 0;
      R[i][j] = 0;
    }
  }
  
  //開(kāi)始計算 
  for(i = 1; i <=lenX; i++)
  {
    for(j = 1; j <=lenY; j++)
    {
      if(X[i-1] == Y[j-1]) //字符串的下標從0開(kāi)始,所以減1,即X1 = X[0] Y1 = Y[0]
      {
        C[i][j] = C[i-1][j-1] + 1;
        R[i][j] = 1;  //由Xi-1和Yj-1,再加上Xi或Yj得到
      }
      else
      {
        if(C[i-1][j] >= C[i][j-1]) 
        {
          C[i][j] = C[i-1][j];
          R[i][j] = 2;   //由Xi-1和Yj得到
        }
        else 
        {
          C[i][j] = C[i][j-1];
          R[i][j] = 3;   //由Xi和Yj-1得到
        }
      }
    }
  }
  //打印最長(cháng)公共子串
  LCS_Print(X, Y, R, lenX, lenY);
  //記錄最大長(cháng)度
  int lcs = C[lenX][lenY];  
  //釋放空間
  for(i = 0; i <= lenX; i++)
  {
    delete [] C[i];
    delete [] R[i];
  }
  delete C;
  delete R;
  R = C = NULL;
  return lcs;
}

      
問(wèn)題2:在字符串中刪除特定元素
    具體描述,輸入兩個(gè)字符串,從第一字符串中刪除第二個(gè)字符串中所有的字符。例如,輸入”They are students.”和”aeiou”,則刪除之后的第一個(gè)字符串變成”Thy r stdnts.”。
    思路:這是字符查找的一個(gè)問(wèn)題,最簡(jiǎn)單的就是考察第二個(gè)字符串的每個(gè)字符,然后檢查第一個(gè)字符串中有沒(méi)有這個(gè)字符,有的話(huà)刪除。這樣的時(shí)間復雜度是O(mn)。對于查找,我們容易想到二分查找、散列這些概念。散列的查找是非???,時(shí)間復雜度為O(1)。如果能聯(lián)想到散列,那么很容易就能給出下面的解法,相信很多人都能想到。需要一個(gè)256字節的數組,記錄第二個(gè)字符串中每個(gè)字符的出現情況,0表示未出現,1表示出現。然后遍歷第一個(gè)字符串,針對每個(gè)字符,去查詢(xún)記錄數組,以決定刪除與否。
   參考代碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//函數功能 : 在字符串中刪除特定字符
//函數參數 : pSrc為源字符串,pDel為特定字符集
//返回值 :  空
void DeleteSpecialChars(char *pSrc, char *pDel)
{
  if(pSrc == NULL || pDel == NULL)
    return;
  int lenSrc = strlen(pSrc);
  int lenDel = strlen(pDel);
  if(lenSrc == 0 || lenDel == 0)
    return;
  bool hash[256] = { false };
  for(int i = 0; i < lenDel; i++) //建立刪除字符的索引
    hash[pDel[i]] = true;
  //開(kāi)始刪除
  char *pCur = pSrc;
  while(*pSrc != '\0')
  {
    if(hash[*pSrc] == false) //不用刪除
      *pCur++ = *pSrc;
    pSrc++;
  }
  *pCur = '\0';
}

問(wèn)題3:左旋轉字符串,其實(shí)也可以左旋數組
   具體描述,定義字符串的左旋轉操作:把字符串前面的若干個(gè)字符移動(dòng)到字符串的尾部。如把字符串a(chǎn)bcdef左旋轉2位得到字符串cdefab。請實(shí)現字符串左旋轉的函數。要求時(shí)間對長(cháng)度為n的字符串操作的復雜度為O(n),輔助內存為O(1)。
   思路:用了一個(gè)小技巧,如果旋轉的字符串為XY,其中Y是要旋轉到X前面的。只要分別將子字符串 X 和 Y 翻轉,然后再將整個(gè)字符串再做一次翻轉即可。STL的一個(gè)算法rotate就是用了這個(gè)。
   參考代碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//函數功能 : 將字符串翻轉
//函數參數 : pBegin指向第一個(gè)字符,pEnd指向最后一個(gè)字符
//返回值 :  空
void ReverseString(char *pBegin, char *pEnd)
{
  if(pBegin == NULL || pEnd == NULL)
    return;
  
  while(pBegin < pEnd)
  {
    //交換字符
    char tmp = *pBegin;
    *pBegin = *pEnd;
    *pEnd = tmp;
    //往中間靠攏
    pBegin++;
    pEnd--;
  }
}
  
//函數功能 : 將字符串左旋 n 位
//函數參數 : pSrc為源字符串,n為左旋位數
//返回值 :  空
void LeftRotateString(char *pSrc, unsigned n)
{
  if(pSrc == NULL || n == 0 || n > strlen(pSrc))
    return;
  
  int len = strlen(pSrc);
  ReverseString(pSrc, pSrc + n - 1);
  ReverseString(pSrc + n, pSrc + len - 1);
  ReverseString(pSrc, pSrc + len - 1);
}

  
問(wèn)題4:在一個(gè)字符串中找到第一個(gè)只出現一次的字符。如輸入abaccdeff,則輸出b。
   思路:這一題不難,因為每個(gè)字符只有8位,因此可以用計數法。首先統計字符串中每個(gè)字符的出現次數,然后從頭遍歷字符串,對于當前字符,查詢(xún)統計表,如果出現的次數為1,則輸出該字符即可。
   參考代碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//函數功能 : 在一個(gè)字符串中找到第一個(gè)只出現一次的字符
//函數參數 : pStr為源字符串
//返回值 :  目標字符
char FirstAppearOnce(char *pStr)
{
  if(pStr == NULL)
    return '\0'; //未找到返回空字符
  
  int count[256] = {0};
  char *pTmp = pStr;
    
  while(*pTmp != '\0') //統計字符串中每個(gè)字符出現的次數
  {
    count[*pTmp]++;
    pTmp++;
  }
  while(*pStr != '\0') //遍歷字符串,找到第一個(gè)只出現一次的字符
  {
    if(count[*pStr] == 1)
      break;
    pStr++;
  }
  return *pStr; //找到的字符
}

      
問(wèn)題5:寫(xiě)一個(gè)函數,它的原形是int continumax(char *outputstr,char *intputstr)。功能:在字符串中找出連續最長(cháng)的數字串,并把這個(gè)串的長(cháng)度返回,并把這個(gè)最長(cháng)數字串付給其中一個(gè)函數參數outputstr所指內存。
        例如:"abcd12345ed125ss123456789"的首地址傳給intputstr后,函數將返回9,outputstr所指的值為123456789
    思路:這一題比較簡(jiǎn)單,掃描一遍字符串即可,遇到數字時(shí)將數字個(gè)數加1,然后與最長(cháng)串比較,如果長(cháng)度大于最長(cháng)串,更新最長(cháng)串;遇到非數字時(shí),將數字計數器清零。
    參考代碼:函數名和形參名修改了一下,個(gè)人習慣。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//函數功能 : 在字符串中找出連續最長(cháng)的數字串
//函數參數 : pSrc表示源串,pDest記錄最長(cháng)數字串的起始位置
//返回值 :  最長(cháng)數字串的長(cháng)度
int ContinueMax(char *pSrc,char * &pDest)
{
  pDest = NULL;
  if(pSrc == NULL)
    return 0;
  
  int max = 0, cnt = 0;
  while(*pSrc != '\0')
  {
    if(*pSrc >= '0' && *pSrc <= '9') //數字
    {
      cnt++;
      if(cnt > max) //更新最長(cháng)的數字串
      {
        pDest = pSrc - cnt + 1;
        max = cnt;
      }
    }
    else
      cnt = 0;
    pSrc++;
  }
  if(cnt > max)
  {
    pDest = pSrc - cnt + 1;
    max = cnt;
  }
  return max;
}

問(wèn)題6:字符串轉換為整數
      問(wèn)題描述:輸入一個(gè)表示整數的字符串,把該字符串轉換成整數并輸出。例如輸入字符串"345",則輸出整數345。
       思路:轉換的過(guò)程比較簡(jiǎn)單,每次讀入一個(gè)字符,將之前保存的值乘以10,然后再加上這個(gè)字符表示的數字。這是正常情況。這個(gè)問(wèn)題主要是考察各種不正常情況的處理。假設函數的聲明為 int StrToInt(const char *str);
       (1)輸入的字符串指針為空;
       (2)數字前面有正負號的處理;
       (3)字符串表示的數字超過(guò)了32位整數能表示的范圍,即溢出處理;
       (4)輸入了非法字符,即除了數字及正負號的其他字符;
       (5)以字符' 0 '開(kāi)始的串,' 0 '后面還跟了其他字符,也是非法的。
        如果能很好的處理這些情況,那么程序的健壯性大大增強。其中有兩種情況處理起來(lái)有點(diǎn)麻煩,第一,如何處理溢出,我們可以使用std::numeric_limits<int>::max(),可以定義一個(gè)long long的變量,然后與這個(gè)最大值相比,從而判斷是否溢出了。第二。由于返回值為一個(gè)整型數,那么如果轉換失敗,返回什么呢?如果是'0 ' ,那么就無(wú)法區分正常輸入"0"的情況。兩種方案,修改函數聲明,通過(guò)返回值表明轉換的成功與否,或者定義一個(gè)全局變量,用來(lái)保存轉換的成功與否。參考代碼中使用了第二種方案。
        參考代碼:先給出的是std::numeric_limits<int>::max()的用法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream>
#include <limits>  //需包含這個(gè)頭文件
using namespace std;
int main() {
  cout << "The maximum value for type float is: "
    << numeric_limits<float>::max( )
    << endl;
  cout << "The maximum value for type double is: "
    << numeric_limits<double>::max( )
    << endl;
  cout << "The maximum value for type int is: "
    << numeric_limits<int>::max( )
    << endl;
  cout << "The maximum value for type short int is: "
    << numeric_limits<short int>::max( )
    << endl;
}
       
bool strToIntOK; //全局的變量 
int StrToInt(const char *str) 
  strToIntOK = false
  if(str == NULL) //空指針 
    return 0; 
     
  if(str[0] == '0' && str[1] != '\0') //以'0'開(kāi)始但不是"0" 這條其實(shí)可以忽略 
    return 0; 
     
  unsigned i = 0; 
  bool minus = false//負數標記 
  if(str[i] == '-' || str[i] == '+') //判斷是不是以正負號開(kāi)始 
  
    minus = (str[i] == '-')? true: false
    i++; 
  
     
  long long result = 0; //轉換的結果 
  while(str[i] != '\0'
  
    char c = str[i++]; 
    if(c >= '0' && c <='9'
    
      result = result * 10 + (c - '0'); 
      if(minus) //負溢出
      {
        if(result - 1 > numeric_limits<int>::max()) 
          return 0; 
      }
      else //正溢出
      {
        if(result > numeric_limits<int>::max())
          return 0; 
      }
    
    else 
    
      return 0; 
    
  
  strToIntOK = true
  //結果返回 需強制轉換一下 
  return minus? (int)(-result):(int)result; 

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
小技巧--巧用ASCII的表示范圍來(lái)對字符串進(jìn)行處理
memcopy和memmove 區別(另strcpy(), strncpy()和memset()) 收藏
SQL字符串函數_鳳舞九天
MySQL的字符串函數大全
SQL常用字符串函數
1.?字符串操作函數
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久