華爲機試訓練做題總結(一)

1.字符串最後一個單詞的長度

題目描述:計算字符串最後一個單詞的長度,單詞以空格隔開。 

思路分析:看到這一題,開始我也沒啥想法,想要去看答案,然後忍住了,稍微想了想,這一題其實挺簡單的。不就是最後單詞的長度,直接跑到字符串的最後,然後朝前數字符串到空格就行了。但是後來看別人的正確答案,發現自己考慮問題還是不夠全面,這一題還需要考慮字符串最後是好幾個空格的情況。因此需要設置一個flag當跑到最後一個單詞的屁股的時候,將其置零。還有一個問題就是輸入的問題,雖然沒有仔細考慮到這個小細節,但是整體的思路還是正確的,但是最後正確率總停留在30%,一直沒想明白,後來明白了。看完OJ的規則,發現不定量的輸入需要使用getline(cin,str),讀取字符串,這樣可以完全讀取字符串。我開始使用的是定義string str,這樣會有一個問題就是輸入的時候會導致輸入斷流。

代碼:

#include<iostream>
#include<string>
using namespace std;
int main(){
    string str;
    while(getline(cin,str)){
  
    int count=0;
    int len=str.length();
    int flag=1;
    for(int i=len-1;i>=0;--i){
      if(flag && str[i]==' ')
          continue;
        else if(str[i]!=' ' ){
            flag=0;
            ++count;
        }else
        {
            break;
        }
    }
    cout<<count<<endl;
}
    return 0;
}


2.計算字符個數

題目描述:寫出一個程序,接受一個有字母和數字以及空格組成的字符串,和一個字符,然後輸出輸入字符串中含有該字符的個數。不區分大小寫。

思路分析:這個代碼只有30%的通過率,百思不得其解。我的主要思想就是通過逆序將最後一個字符提取,然後再重新順序遍歷空格之前的字符串,與提取的字符相同的就計數。講道理,應該不會有問題,求大神解答!

代碼:

#include<iostream>
#include<string>
using namespace std;
int main(){
    string str;
    char com;
    int endnum=0;
    while(getline(cin,str))
    {
        int len=str.length();
        int flag=1;
        for(int i=len-1;i>=0;i--)
        {
            if(flag && str[i]==' ')
            {
                continue;
            }else if(str[i]!=' '){
                flag=0;
                com=str[i];
                endnum=i;
                break;
            }else
                break;
            
        }
        
    }
    int count=0;
    for(int i=0;i<(endnum-1);i++){
        char res=str[i];
        if(res==com || res==(com-32))
          count++;
    }
    cout<<count<<endl;
    return 0;
}


3.明明的隨機數

題目描述:明明想在學校中請一些同學一起做一項問卷調查,爲了實驗的客觀性,他先用計算機生成了N個1到1000之間的隨機整數(N≤1000),對於其中重複的數字,只保留一個,把其餘相同的數去掉,不同的數對應着不同的學生的學號。然後再把這些數從小到大排序,按照排好的順序去找同學做調查。請你協助明明完成“去重”與“排序”的工作。

思路分析:開始把題目想錯了,其實這個題目是提供隨機數的  不需要自己生成,所以是多case問題,因此需要採用while(cin>>n)進行輸入,然後將還有一個就是set 這個數據庫的掌握,set通過insert進行輸入,並且set這個數據結構只允許出現一次,並且在其中進行排好序了,複雜度在log2.非常高效的數據結構。對set數據結構進行遍歷採用指針 set<int>::const_iterator p。


還有一個非常巧妙的桶排序,就是輸入的每個數作爲下標,然後進行計數,然後再遍歷就是了。注意的是,數組需要在while循環內進行初始化。

代碼:

#include<iostream>
#include<set>
using namespace std;
int main(){
    int n;


    set<int>res;
    int temp;
    while(cin>>n){
    for(int i=0;i<n;i++){
        cin>>temp;
        res.insert(temp);
        
    }
    for(set<int>::const_iterator p= res.begin();p!=res.end();p++)
    {
        cout<<*p<<endl;
        
    }
    res.clear();
    }
    return 0;
}

4.字符串分隔

題目描述:•連續輸入字符串,請按長度爲8拆分每個字符串後輸出到新的字符串數組; 
•長度不是8整數倍的字符串請在後面補數字0,空字符串不處理。 

思路分析:這一題還是比較簡單,主要思路就是整除和求餘,如果遇到八的倍數就記錄下來,然後按照八的倍數進行輸出,然後餘數判斷,只要是存在餘數就輸出然後再後面補上‘0’就行,然後不用考慮輸入幾次的問題,只要一勁兒輸入就行,因爲用的while(cin>>n)

代碼:

#include<iostream>
#include<string>
using namespace std;
int main(){
    string str;
    while(cin>>str){
        int len=str.length();
        int yu=len%8;
        int beishu=len/8;
        for(int i=0;i<beishu;i++)
        {
            for(int j=0+8*i;j<8+8*i;j++)
            {
                cout<<str[j];
            }
            cout<<endl;
        }
        for(int i=beishu*8;i<beishu*8+yu;i++)
        {
            cout<<str[i];
            
        }
        if(yu!=0){
            
        for(int i=beishu*8+yu;i<8+beishu*8;i++)
        {
            cout<<'0';
        }
            cout<<endl;
        }
        
        
    }
    return  0;
    
}

5.進制轉換

題目描述:寫出一個程序,接受一個十六進制的數值字符串,輸出該數值的十進制字符串。(多組同時輸入 

思路分析:因爲題目提示的是多組進行輸入因此需要採用while(cin>>string),不然會出現錯誤,然後還有一個就是最終輸出的定義一定要放在while的循環內部,不然輸出也會出現錯誤。

代碼:

#include<iostream>
#include<math.h>
#include<string>
using namespace std;
int main(){
    //進制轉換一般就是  先除以該進制,然後轉換爲二進制  然後二進制轉換爲十進制
    string str;
    
    
    while(cin>>str){
        int res=0;
    for(int i=2;i<str.size();i++){
        
        if(str[i]<='F' && str[i]>='A')
        {
            res=(str[i]-'A'+10)*pow(16,(str.size()-i-1))+res;
        }
        if(str[i]<='9'  && str[i]>='0')
        {
            res=(str[i]-'0')*pow(16,(str.size()-i-1))+res;
        }
        
    }
    cout<<res<<endl;
    }
    return 0;
    
}

6.質數因子

題目描述:

功能:輸入一個正整數,按照從小到大的順序輸出它的所有質數的因子(如180的質數因子爲2 2 3 3 5 )

最後一個數後面也要有空格

思路分析:這一題剛拿到手,我表示我是悶逼的,我一想直接就是質數,那怎麼求出所有的質數呢。這是直接就固定思維 了。其實換個角度想想,求質數分解其實就是從最小的2,3開始分解的,如果這些比較小的數,都被分解完才能輪到比較大的數,因此直接就是循環,2分解一次,再分解一次,不能被2分解了再加,最終就能求出所有的質數。

代碼:

#include<iostream>


using namespace std;
int main(){
    long input_data;
    while(cin>>input_data){
        while(input_data!=1){
        for(int i=2;i<=input_data;i++)
        {
            if(input_data%i==0)
            {
                input_data=input_data/i;
                cout<<i<<" ";
                break;
            }
        }
        }
        
    }
    return 0;
    
}


7.取近似值

題目描述:

功能:

寫出一個程序,接受一個正浮點數值,輸出該數值的近似整數值。如果小數點後數值大於等於5,向上取整;小於5,則向下取整。

思路分析:這一題,我也不知道怎麼說就是一個int double / %的應用

代碼:

#include<iostream>
using namespace std;
int main(){
    double res;
    while(cin>>res){
        int temp=(int)res;
        res=res*10;
        temp=res-temp*10;
        if(temp>=5)
            res=int(res)/10+1;
        else
            res=int(res)/10;
            
        cout<<res; 
        
    }
    return 0;
    
}


8.合併表記錄

題目描述:數據表記錄包含表索引和數值,請對錶索引相同的記錄進行合併,即將相同索引的數值進行求和運算,輸出按照key值升序進行輸出。

思路分析:這一題有相同項的相加,由於之前遇到過一題類似的,一下子想到了水桶排序,思路很簡單,做的過程,還需要注意細節,其他都還好,哈哈哈。

代碼:

#include<iostream>
#include<vector>
using namespace std;
int main(){
    int n;
    while(cin>>n){
        vector<int>res(1000,0);
        int temp1;
        int temp2;
      for(int i=0;i<n;i++){
            cin>>temp1;
            cin>>temp2;
            res[temp1]=res[temp1]+temp2;
        }
        for(int i=0;i<1000;i++)
        {
            if(res[i]!=0)
            {
                cout<<i<<" "<<res[i]<<endl;
            }
        }
    
    }
    return 0;

}



9.提取不重複的整數

題目描述:輸入一個int型整數,按照從右向左的閱讀順序,返回一個不含重複數字的新的整數。

思路分析:這一題主要思路就是把重複的都剔除然後反過來讀出,實際上就是在剔除上要花功夫,我採用的是遍歷,如果和前面一致我就不存,並且設置一個哨兵,如果有和前面的一致的我就不增加計數。常規思路吧。

代碼:

#include<iostream>
#include<vector>
#include<math.h>
using namespace std;
int main(){
    int n;
    while(cin>>n){
        vector<int>res(100,0);
        int temp=0;
        int counter=0;
        int flag=0;
        res[0]=n%10;
        n=n/10;
        while(n!=0){
            temp=n%10;
            counter++;
            flag=0;
            for(int i=0;i<counter;i++){
            if(temp==res[i])
            {
                flag=1;
                counter--;
                break;
            }  
            }  
            if(flag==0){
                res[counter]=temp;
            }
            n=n/10;
        }
        
        int new_num=0;
        for(int i=0;i<=counter;i++){
            new_num=new_num+res[i]*pow(10,counter-i);
            
        }
        cout<<new_num;
    }


    return 0;
}


10.字符個數統計

題目描述:

編寫一個函數,計算字符串中含有的不同字符的個數。字符在ACSII碼範圍內(0~127)。不在範圍內的不作統計。

思路分析:這一題也是典型的水桶排序題,就是設置一個那麼大的數組然後將對應的元素輸入進去,但是這裏,我搞錯了一個東西,就是數組大於0,就是存在至少含有一個字符的個數。

代碼:

#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main(){
    string str;
    while(cin>>str){
        int temp=0;
        int count=0;
        vector<int>res(128,0);
        for(int i=0;i<str.length();i++){
            
            temp=str[i]-' ';
            if(temp<128 && temp>=0)
            res[temp]++;
        }
        for(int i=0;i<127;i++){
            if(res[i]>0)
                count++;
        }
        cout<<count;
    }
    return 0;
}


11.數字顛倒

題目描述:

輸入一個整數,將這個整數以字符串的形式逆序輸出

程序不考慮負數的情況,若數字含有0,則逆序形式也含有0,如輸入爲100,則輸出爲001

思路分析:這一題我真不知道該怎麼說了,實在是太搞笑了,我想多了實際就是直接輸出一個加上‘0’的字符就行,主體考察的就是一個整除和求餘的操作。

代碼:

#include<iostream>
#include<string>
using namespace std;
int main(){
    int num;
    while(cin>>num){
        char temp;
        while(num){
            temp=num%10+'0';
            cout<<temp;
            num/=10;
        }
    }
    return 0;
}


12.字符串反轉

題目描述:

寫出一個程序,接受一個字符串,然後輸出該字符串反轉後的字符串。例如:

思路分析:這一題我真不知道該怎麼說了,實在是太搞笑了,其實這一題就是你明白了OJ系統之後鑽的一個空子。

代碼:

#include<iostream>
#include<string>
using namespace std;
int main(){
    string str;
    while(cin>>str){
        for(int i=str.length()-1;i>=0;i--)
        {
           cout<<str[i]; 
        }
    }
    return 0;
}


13.句子逆序

題目描述:

將一個英文語句以單詞爲單位逆序排放。例如“I am a boy”,逆序排放後爲“boy a am I”
所有單詞之間用一個空格隔開,語句中除了英文字母外,不再包含其他字符


接口說明

/**
 * 反轉句子
 * 
 * @param sentence 原句子
 * @return 反轉後的句子
 */
public String reverse(String sentence);


思路分析:這一題主體思想沒啥大的問題,但是在輸入的時候和細節把握髮現很多問題。比如輸入的問題是cin>>怎麼都沒法使程序通過,然而之前使用cin毫無問題,之後換了getline(cin,str)問題就解決了,我不知道具體的原因,我猜想是這個問題的特殊,造成的。因爲輸入的是句子,最終是要有回車的。因此採用cin無法使回車產生作用。還有一個細節的問題就是最後一個字符串的出現,沒有考慮好,應該對最後一個字符進行單獨考慮。

代碼:

#include<iostream>
#include<string>
using namespace std;
int main(){
    string str;
    while(getline(cin,str)){
        
for(int i=str.length()-1;i>0;i--){
            if(str[i]==' '){
                for(int j=i+1;str[j]!=' ' && j<(str.length());j++)
                {
                    cout<<str[j];
                }
                cout<<' ';
            }
        }
        for(int i=0;str[i]!=' ';i++){
            cout<<str[i];
        }
    }
    return 0;
}


14.字符串連接最長路徑的查找

題目描述:

給定n個字符串,請對n個字符串按照字典序排列。

思路分析:這一題其實也很簡單,關鍵點就兩個遍歷和比較,遍歷我用的最笨的方法,雙重循環,比較我比較犯傻,沒有掌握string的特殊特性,string類型自帶比較屬性,我還吭哧地寫了個函數,結果那個函數還是錯的,跪 了。需要注意的是vector<string>str(n)需要給出n的大小,然後比較,最後還要有clear函數,不然可能會溢出。還有雙重循環的時候注意起始。

代碼:

#include<iostream>
#include<string>
#include<vector>
#include<math.h>
#include<algorithm>
using namespace std;
int main(){
    int n;
    while(cin>>n){
        vector<string>str(n);


        for(int i=0;i<n;i++){
            
            cin>>str[i];
        }
        string temp;
        for(int i=0;i<n-1;i++)
        {
            for(int j=i+1;j<n;j++){
                if(str[i]>str[j])
                {
                    temp=str[i];
                str[i]=str[j];
                    str[j]=temp;
                }
            }
        }
        for(int i=0;i<n;i++){
           cout<<str[i]<<endl; 
        }
        str.clear();
    }
    
    return 0;
}

15.求int型正整數在內存中存儲時1的個數

題目描述:

輸入一個int型的正整數,計算出該int型數據在內存中存儲時1的個數。

思路分析:這一題感覺還是基礎不夠紮實啊,別人都用很精妙的方法求的,感覺自己的差距還是有的。回到正題一個,就是利用對數字求2的餘,判斷是否有1,對2求商逐位判斷。還有一個就是利用 a&=a-1;//判斷二進制有多少個1

代碼:

#include<iostream>
using namespace std;
int main(){
    int num;
    while(cin>>num){
        int count=0;
        while(num){
            if(num%2)
            count++;
            num/=2;
        }
        cout<<count;
    }
    return 0;

}


16.購物車

題目描述:

王強今天很開心,公司發給N元的年終獎。王強決定把年終獎用於購物,他把想買的物品分爲兩類:主件與附件,附件是從屬於某個主件的,下表就是一些主件與附件的例子:
主件 附件
電腦 打印機,掃描儀
書櫃 圖書
書桌 檯燈,文具
工作椅
如果要買歸類爲附件的物品,必須先買該附件所屬的主件。每個主件可以有 0 個、 1 個或 2 個附件。附件不再有從屬於自己的附件。王強想買的東西很多,爲了不超出預算,他把每件物品規定了一個重要度,分爲 5 等:用整數 1 5 表示,第 5 等最重要。他還從因特網上查到了每件物品的價格(都是 10 元的整數倍)。他希望在不超過 N 元(可以等於 N 元)的前提下,使每件物品的價格與重要度的乘積的總和最大。
    設第 j 件物品的價格爲 v[j] ,重要度爲 w[j] ,共選中了 k 件物品,編號依次爲 j 1 , j 2 ,……, j k ,則所求的總和爲:
v[j 1 ]*w[j 1 ]+v[j 2 ]*w[j 2 ]+ … +v[j k ]*w[j k ] 。(其中 * 爲乘號)
    請你幫助王強設計一個滿足要求的購物單。

思路分析:實在是吐了,啥不想看了,想死,就是一個動態規劃問題,需要存儲值,然後採用動態規劃把結果計算出來, 判斷不同的情況,可以採用多種判斷的語句。

但是也學到了一些看似沒用的東西:


萬能的頭文件:#include<bits/stdc++.h>


cnt表示計數


1<<j  1向左位移j個單位


代碼:

#include <iostream>
#include <algorithm>
 
#define max(x,y) (x)>(y)?(x):(y)
 
using namespace std;
 
int main()
{
    int N,m;   //N 總錢數  m爲購買物品個數
    int weight[61][3]={0};
    int value[61][3] = {0};
     
    while(cin>>N>>m)
    {
        int dp[61][3201] = {0};
        N /= 10;    //都是10的整數倍 節約空間
        int v,p,q;
        for(int i=1;i<=m;i++)
        {
            cin>>v>>p>>q;
            p = p*v;
            v /= 10;
            //按主件附件分類  第二個小標表示是第i件物品還是主件附件
            if(q==0)
            {
                weight[i][q] = v;
                value[i][q] = p;
            }
            else if(weight[q][1]==0)
            {
                weight[q][1] = v;
                value[q][1] = p;
            }
            else
            {
                weight[q][2] = v;
                value[q][2] = p;
            }
             
        }
 
        //開始進行動態規劃
        for(int i=1;i<=m;i++)
            for(int j=1;j<=N;j++)
            {
                dp[i][j] = dp[i-1][j];
                if(weight[i][0]<=j)
                {
                    int t = max(dp[i-1][j],dp[i-1][j-weight[i][0]]+value[i][0]);
                    if(t>dp[i][j])
                        dp[i][j] = t;
                }
                if(weight[i][0]+weight[i][1]<=j)
                {
                    int t = dp[i-1][j-weight[i][0]-weight[i][1]]+value[i][0]+value[i][1];
                    if(t>dp[i][j])
                        dp[i][j] = t;
                }
                if(weight[i][0]+weight[i][2]<=j)
                {
                    int t = dp[i-1][j-weight[i][0]-weight[i][2]]+value[i][0]+value[i][2];
                    if(t>dp[i][j])
                        dp[i][j] = t;
                }
                if(weight[i][0]+weight[i][1]+weight[i][2]<=j)
                {
                    int t = dp[i-1][j-weight[i][0]-weight[i][1]-weight[i][2]]+value[i][0]+value[i][1]+value[i][2];
                    if(t>dp[i][j])
                        dp[i][j] = t;
                }
            }
 
        cout<<dp[m][N]<<endl;
 
    }
    return 0;

}

17.座標移動

題目描述:

開發一個座標計算工具, A表示向左移動,D表示向右移動,W表示向上移動,S表示向下移動。從(0,0)點開始移動,從輸入字符串裏面讀取一些座標,並將最終輸入結果輸出到輸出文件裏面。

思路分析:這一題思路主要就是就是字符串和數字之間的關係,還有一個就是尋找;之間的字符個數,這一題停留了挺長時間的,主要的問題出在了一個循環上面,其中的判斷條件沒有用對,再加上不太會debug找到問題的所在,所以一直愣在這兒,沒有繼續朝下做。

感悟:一個就是要把其中要輸出的部分寫在while循環裏面,還有一個就是debug 的技巧就是將不同的部分註釋掉,然後只留下想debug的部分。

#include<bits/stdc++.h>
using namespace std;
int main(){
    string str;
      
      
    while(getline(cin,str)){
        //設置初始座標  和 移動數值
        int x=0;
        int y=0;
        int dx=0;
        int dy=0;
  int tempj=0;
int tempi=0;
       for(int i=0;i<str.length();i++){
            tempi=i;
           if(str[i]==';' )
           {
               
               int count=0;
               for(int j=tempi-1;j>=0 && str[j]!=';';j--)
               {
                   if(str[j]<='Z' && str[j]>='A' &&  str[j]!='A' && str[j]!='D' && str[j]!='W' && str[j]!='S')
                   {
                      count=2; 
                   }
                   if(str[j]=='A' || str[j]=='D' || str[j]=='W' || str[j]=='S'){
                      count++; 
                   }
                   tempj=j;
               }
               
               if(count>=2)
               break;
               if(str[tempj]=='A')
               {
                   for(int k=tempj+1;k<tempi;k++)
                   {
                       dx+=-(str[k]-'0')*pow(10,tempi-k-1);
                       
                   } 
               }
               if(str[tempj]=='D')
               {
                   for(int k=tempj+1;k<tempi;k++)
                   {
                       dx+=(str[k]-'0')*pow(10,tempi-k-1);
                       
                   } 
               }
               if(str[tempj]=='W')
               {
                   for(int k=tempj+1;k<tempi;k++)
                   {
                       dy+=(str[k]-'0')*pow(10,tempi-k-1);
                       
                   } 
               }
               if(str[tempj]=='S')
               {
                   for(int k=tempj+1;k<tempi;k++)
                   {
                       dy+=-(str[k]-'0')*pow(10,tempi-k-1);
                       
                   } 
               }
           }else
               continue;
       }
        x=dx;
        y=dy;
        cout<<x<<","<<y<<endl;
    }


    return 0;
}

18.識別有效IP地址和掩碼並進行分類統計

題目描述:

請解析IP地址和對應的掩碼,進行分類識別。要求按照A/B/C/D/E類地址歸類,不合法的地址和掩碼單獨歸類。

思路分析:到最後這一題我也沒看懂,主要不知道 這一題的標準是是是什麼,然後通過看別


人通過的代碼,大體懂了一些,然後主要學習到了string和int 兩個類型之間轉換的方式


主要通過 atoi(str.c_str())函數實現string到int 類型的轉換(其中c_str()是將string 轉


爲 char* 類型)。然後是string這個數據結構中substr函數的應用,str.substr(子串開始


的位置,子串的長度),還有一個就是string數據結構find函數的應用,str.find(' ~')    發


現字符在原字符串中的位置。


還有一個有疑問的地方就是自己寫了一個函數什麼時候使用引用,什麼時候不用使用引


用,這個地方比較疑惑。


#include<iostream>
#include<string>
#include<vector>
using namespace std;


void split(string& str, vector<string>& strs){
    int pos=str.find('.');
    while(pos>=0){
        strs.push_back(str.substr(0, pos));
        str=str.substr(pos+1, str.length()-pos-1);
        pos=str.find('.');
    }
    strs.push_back(str);
}


bool checkNum(string& str){
    if(str.size()==0 || str.size()>3)
        return false;
    for(int i=0; i<str.size(); i++){
        if(str[i]<'0' || str[i]>'9')
            return false;
    }
    int num=atoi(str.c_str());
    if(num>=0 && num<=255)
        return true;
    return false;
}


bool checkIP(vector<string>& segs){
    if(segs.size()!=4)
        return false;
    for(int i=segs.size()-1; i>=0; i--){
        if(!checkNum(segs[i]))
            return false;
    }
    //if(atoi(segs[0])==127)
    //    return false;
    return true;
    
}


bool checkMask(vector<string>& segs){
    if(segs.size()!=4)
        return false;
    bool start=false;
    for(int i=0; i<segs.size(); i++){
        if(!checkNum(segs[i]))
            return false;
        int num=atoi(segs[i].c_str());
        if(start){
            if(num!=0)
                return false;
        }else{
            if(num!=255){
                if(num==0 || num==128 || num==192 || num==224 || num==240 || num==248 || num==252 || num==254)
                    start=true;
                else
                    return false;
            }
        }   
    }
    if(atoi(segs[3].c_str())==255)
        return false;
    return true;
}


void classify(vector<string>& ip, vector<int>& counter){
    int n1=atoi(ip[0].c_str());
    int n2=atoi(ip[1].c_str());
    if(n1>=1 && n1<=126){
        if(n1==10)
            counter[6]++;
        counter[0]++;
    }else if(n1>=128 && n1<=191){
        if(n1==172 && n2>=16 && n2<=31)
            counter[6]++;
        counter[1]++;
    }else if(n1>=192 && n1<=223){
        if(n1==192 && n2==168)
            counter[6]++;
        counter[2]++;
    }else if(n1>=224 && n1<=239)
        counter[3]++;
    else if(n1>=240 && n1<=255)
        counter[4]++;
}


int main(){
    vector<int> counter(7, 0);
    int W=0, P=0;
    string str;
    while(cin>>str){
        int pos=str.find('~');
        string ip=str.substr(0, pos);
        string mask=str.substr(pos+1, str.length()-pos-1);
        vector<string> ip_segs, mask_segs;
        split(ip, ip_segs);
        split(mask, mask_segs);
        if(!checkIP(ip_segs) || !checkMask(mask_segs))
            counter[5]++;
        else
            classify(ip_segs, counter);
    }
    cout<<counter[0]<<" "<<counter[1]<<" "<<counter[2]<<" "<<counter[3]<<" "<<counter[4]<<" "<<counter[5]<<" "<<counter[6]<<endl;
    return 0;
}


19.簡單錯誤記錄

題目描述:

開發一個簡單錯誤記錄功能小模塊,能夠記錄出錯的代碼所在的文件名稱和行號。

思路分析:

這一題很奇怪,明明我輸出的內容和對應的輸出是一樣的,但是還是沒有通過,但是代碼還是要貼出來的。通過這一題,學到了很多關於string類型吧函數的使用方法,以及一些特殊的關鍵字。


比如: string 的rfind函數:


就是發現字符串中指定字符所在最後一個位置的函數,通過這個函數你可以方便的找到


最後一次出現該字符的位置。



string類型的substr函數:


substr(pos),就是表示直接從pos位置向後的子字符串,還有一種表示方式是


substr(pos,length),表示從pos位置向後length距離的子字符串。



結構體的使用:


結構體最早接觸是在c語言中,當時學習學的也是稀裏糊塗,純粹爲了考試,並沒有真


正想着如何取用。這一題中結構通過將兩個判別數據以及一個存儲數據放進來。並且實   

現了運算符重載(這讓我非常驚訝,結構體竟然能夠運算符重載!!!) 還有一個讓我


非常驚訝的就是結構體,竟然能和數據類型一樣存在vecotr裏面!!!直接就是一種數


據類型。其中結構體的變量賦值直接就是在結構體裏面構造初始化函數和類的寫法一


樣。


vector查詢相同變量內容:


可能這裏我的話沒說清楚,意思就是查詢一個vector類型存儲的內容裏面有沒有我們想


要的內容。這個查找方法是 auto res=find(myvec.begin(),myvec.end(),temp);


如果res==myvec.begin()就說明這個裏面不存在,我們想找的temp。


其中res的類型,也可以是vector<erroNode>::iterator 就是一個指針類型,查找元素用


的。




貼代碼:

#include<bits/stdc++.h>
using namespace std;
string getFileName(string path){
    int pos=path.rfind('\\');
    return path.substr(pos+1);
}


string modifyName(string name){
    if(name.size()>16){
        name=name.substr(name.size()-16);
    }
    return name;
}
struct ErrRecord{
    string file;
    int lineNo;
    int count;
    ErrRecord(string file,int lineNo){
        this->file=file;
        this->lineNo=lineNo;
        count=1;
    }
    bool operator ==(const ErrRecord &a){
        return (file== a.file) && (lineNo == a.lineNo);
    }
};
int main(){
    string file;
    int lineNo;
    vector<ErrRecord>myvec;
    while(cin>>file>>lineNo){
        ErrRecord record(getFileName(file),lineNo);
        auto res=find(myvec.begin(),myvec.end(),record);
        if(res==myvec.end()){
            myvec.push_back(record);
        }else{
            res->count++;
        }
    }
    int count=0;
    for(auto item:myvec){
        if(count+8 >=myvec.size()){
            cout<<modifyName(item.file)<<" "<<item.lineNo<<" "<<item.count<<endl;
            
        }
        count++;
        
    }
    return 0;
}


20.密碼驗證合格程序

題目描述:

密碼要求:

 

 

 

1.長度超過8位

 

 

 

2.包括大小寫字母.數字.其它符號,以上四種至少三種

 

 

 

3.不能有相同長度超2的子串重複

 

 

 

說明:長度超過2的子串

思路分析:

這一題思路還是比較簡單的,就是將三個條件進行判斷就行了,開始還在爲自己一遍通過,感覺沾沾自喜,後來看到了大神的AC,感覺自己還是個老實人,沒有將效率進一步提高。實判斷子字符串完全可以只判斷三個長度的子字符串,因爲大於三個長度的子字符串完全是不用對比的。


老實人的代碼:

#include<bits/stdc++.h>
using namespace std;
//寫一個函數判斷符號的種類
bool modifyNote(string str){
    vector<int>count(4,0);
    int zero_num=0;
    for(int i=0;i<str.length();i++){
        if(str[i]>='A' && str[i]<='Z')
        {
            count[0]++;
        }else if(str[i]>='a' && str[i]<='z')
        {
            count[1]++;
        }else if(str[i]>='0' && str[i]<='9')
        {
            count[2]++;
        }else
        {
            count[3]++;
        }
        
    }
    for(int i=0;i<4;i++)
    {
        if(count[i]==0)
            zero_num++;
    }
    if(zero_num<=1)
        return false;
    else
        return true;
}
//寫一個函數用來判斷長度超過2的子串 是否有重複的子字符串
//返回true 說明有相同的子字符串  返回false 則說明沒有相同的子字符串。
bool substr_judge(const  string str ){
    string sub_str;
    for(int i=0;i<str.length();i++){
        for(int j=3;j<str.length();j++){
        sub_str=str.substr(i,j);
          //開始進行對比
           for(int k=i+1;k<(str.length()-j);k++){
               if(sub_str==str.substr(k,j))
                   return true;
               
           }
        }
    }
    return false;
}
int main(){
    string str;
    while(cin>>str){
        if(str.length()<=8)
        {
            cout<<"NG"<<endl;
        }else if(substr_judge(str)){
            cout<<"NG"<<endl;
        }else if(modifyNote(str))
        cout<<"NG"<<endl;
        else 
            cout<<"OK"<<endl;
    }
    
    return 0;
}


21.簡單密碼

題目描述:

假設淵子原來一個BBS上的密碼爲zvbo9441987,爲了方便記憶,他通過一種算法把這個密碼變換成YUANzhi1987,這個密碼是他的名字和出生年份,怎麼忘都忘不了,而且可以明目張膽地放在顯眼的地方而不被別人知道真正的密碼。

思路分析:

這一題不難,但是還是停留了好長時間,這主要是因爲,遇到一個很坑的一個東西,就是你在if語句判斷的時候,


能用if-elseif就儘量用,別用if-if 不然華爲OJ很容易出錯!!!



代碼:


#include<bits/stdc++.h>
using namespace std;
int main(){
    //變換主要針對於大小寫字母 其他都不變
    string str;
    while(cin>>str){
        int num=('a'-'A')+1;
        for(int i=0;i<str.length();i++){
            if(str[i]=='Z')
                str[i]='a';
            else if(str[i]>='A' && str[i]<'Z'){
               
                str[i]=(char)(str[i]+num);
            }else if(str[i]>='a' && str[i]<='z'){
                switch(str[i]){
                     case 'a':
                     case 'b': 
                     case 'c':
                        { str[i]='2';
                        break;
                        }
                    case 'd':
                    case 'e': 
                    case 'f':
                      {
                          str[i]='3';
    break;
                      }  
                    case 'g':
                    case 'h': 
                    case 'i':
                      {
                          str[i]='4';
break;
                      } 
                    case 'j':
                    case 'k':
                    case 'l':
                      {
                          str[i]='5';
              break;
                      }
                    case 'm':
                    case 'n':
                    case 'o':
                      {
                          str[i]='6';
    break;
                      }
                    case 'p':
                    case  'q':
                    case  'r':
                     case 's':
                      {
                          str[i]='7';
break;
                      }
                    case 't':
                    case 'u':
                    case 'v':
                      {
                          str[i]='8';
        break;
                      }
                    case 'w':
                    case'x': 
                    case 'y':
                    case 'z':
                      {
                          str[i]='9';
break;
                      }  
                }
                
            }
        }
         cout<<str<<endl;
      
      }
        


    return 0;
}

22.汽水瓶

題目描述:

有這樣一道智力題:“某商店規定:三個空汽水瓶可以換一瓶汽水。小張手上有十個空汽水瓶,她最多可以換多少瓶汽水喝?”答案是5瓶,方法如下:先用9個空瓶子換3瓶汽水,喝掉3瓶滿的,喝完以後4個空瓶子,用3個再換一瓶,喝掉這瓶滿的,這時候剩2個空瓶子。然後你讓老闆先借給你一瓶汽水,喝掉這瓶滿的,喝完以後用3個空瓶子換一瓶滿的還給老闆。如果小張手上有n個空汽水瓶,最多可以換多少瓶汽水喝? 

思路分析:

這一題一遍過,掌握了規律真的很簡單。然後這個規律是我猜的。

代碼:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int num;
    while(cin>>num){
        if(num==0)
            break;
        num=num/2;
        cout<<num<<endl;
    }
   return 0; 
}


23.刪除字符串中出現次數最少字符

題目描述:

實現刪除字符串中出現次數最少的字符,若多個字符出現次數一樣,則都刪除。輸出刪除這些單詞後的字符串,字符串中其它字符保持原來的順序。 

思路分析:

這一題邏輯難度不大,常規的一套思路走下來,基本就能完成,但是實現的時候,感覺難度還是有的,花了挺長時間的,感覺功力還是需要加強的

代碼:

#include<bits/stdc++.h>
using namespace std;
int main(){
    string str;
    while(cin>>str){
        int temp=20;
        vector<int>pos;
        vector<int>counter(26,0);
        for(int i=0;i<str.length();i++){
            counter[str[i]-'a']++;
        }
        for(int i=0;i<26;i++){
            if(counter[i]<=temp && counter[i]!=0){ 
                temp=counter[i];
            }
        }
       for(int i=0;i<str.length();i++){
           if(temp==counter[str[i]-'a'])
               continue;
           else
               cout<<str[i];
       }
        cout<<endl;
        
    }
    return 0;

}

24.數據分類處理

題目描述:

信息社會,有海量的數據需要分析處理,比如公安局分析身份證號碼、 QQ 用戶、手機號碼、銀行帳號等信息及活動記錄。  

採集輸入大數據和分類規則,通過大數據分類處理程序,將大數據分類輸出。


思路分析:

這一題也想了一種解決的思路出來,但是後來解決的方法越來越負責,直接就放棄了。 後來找了一種還算比較簡單的,思路還比較類似的。然後講講主要是怎麼實現的吧。主要就是利用

vector先存儲主要的元素,然後利用set這種數據結構排序去重的屬性,先存儲R類,然後再將其元素存儲到vector數據結構中,然後利用stringstream將int轉爲string類型,然後利用find函數,發現子字符串的話find返回值就是 string::npos,然後如果符合條件的就放進結果的向量裏面並且技術

感悟:

int->string 

採用stringstream temp, string str; temp<<int_num; temp>>str;

set數據結構

採用set數據結構可以直接進行排序去重,同時插入形式是insert();

vector類型

vector進行排序的函數sort(vec.begin(),vec.end());vector 進行整段插入採用

採用的是insert()函數,insert(result.end(),temp.begin(),temp.end());其中

insert(result.begin(),val),表示在最前面插入元素值

insert(result.end(),val),表示在最後插入元素。

string類型

string 類查找字符串中是否有子串可以通過find函數,str.find(substr),如果返回值是std::string::npos 則說明字符串中存在需要查找的子串。

同時回顧一下之前的rfind函數,就是發現字符串中指定字符所在最後一個位置的函數,通過這個函數你可以方便的找到最後一次出現該字符的位置。


代碼:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    while(cin>>n){
        vector<int>I(n);
        for(int i=0;i<n;i++){
            cin>>I[i];
        }
        int m;
        cin>>m;
        set<int>temp;
        for(int i=0;i<m;i++){
            int a;
            cin>>a;
            temp.insert(a);
        }
        vector<int>R;
        set<int>::iterator iter=temp.begin();
        while(iter!=temp.end()){
            R.push_back(*iter);
            ++iter;
        }
        sort(R.begin(),R.end());
        vector<int>result;
        for(int i=0;i<R.size();i++){
            stringstream ss1;
            string str1;
            ss1<<R[i];
            ss1>>str1;
            int ret=0;
            vector<int>temp_result;
            for(int j=0;j<n;j++){
                stringstream ss;
                string str;
                ss<<I[j];
                ss>>str;
                size_t found=str.find(str1);
                if(found!=std::string::npos){
                    temp_result.push_back(j);
                    temp_result.push_back(I[j]);
                    ret++;
                }
               
            }
            if(ret){
                result.push_back(R[i]);
                result.push_back(ret);
                result.insert(result.end(),temp_result.begin(),temp_result.end());


            }
        }
        result.insert(result.begin(),result.size());
        for(int i=0;i<result.size()-1;i++){
            cout<<result[i]<<" "<<endl;
            
        }
        cout<<result[result.size()-1]<<endl; 
    }
    return 0;

}

25.字符串排序

題目描述:


寫一個程序,將輸入字符串中的字符按如下規則排序。

規則 1 :英文字母從 A  Z 排列,不區分大小寫。

       如,輸入: Type   輸出: epTy

規則 2 :同一個英文字母的大小寫同時存在時,按照輸入順序排列。

     如,輸入: BabA   輸出: aABb

規則 3 :非英文字母的其它字符保持原來的位置。

     如,輸入: By?e   輸出: Be?y

樣例:

    輸入:

   A Famous Saying: Much Ado About Nothing(2012/8).

    輸出:

   A  aaAAbc   dFgghh  iimM  nNn   oooos   Sttuuuy (2012/8).


思路分析:

其實這一題總有一種一眼看穿的感覺,總有種一下子就能做出來的感覺,但是 看了好久還是沒有進展,後來看看別人的做法,發現其實初始的想法還是已經和解決方案還是很近了。但是沒有堅持下去。可惜。

但是需要注意的地方還是有很多的。

比如vector<char>temp 變量的設置,需要將vector裏面的類型設置爲char不然無法進行push_back。

另外一個需要注意的地方就是核心,需要將從1-26個字母依次存儲就是依次減去'a'  'A'之後對應的數字。

還有一個就是將排好順序的字符串賦值給原來的字符串的地方需要注意。

代碼:


#include<bits/stdc++.h>
using namespace std;
int main(){
    string str;
    vector<char>temp;
    while(cin>>str){
temp.clear();
        for(int i=0;i<26;i++){
            for(int j=0;j<str.size();j++){
                if(str[j]-'a'==i || str[j]-'A'==i){
                    temp.push_back(str[j]);
                }
                
            }   
        }
        for(int i=0 ,j=0;i<str.size() && j<temp.size();i++){
            if(str[i]>='a' && str[i]<='z' || str[i]>='A' && str[i]<='Z'){
                str[i]=temp[j++];
            }
            
            
        }
        cout<<str<<endl;
        
    }


   
    return 0;
}



發佈了54 篇原創文章 · 獲贊 120 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章