1. 程式人生 > >C++刷題

C++刷題

劍指Offer系列

賦值運算子函式

描述

為Class新增賦值運算子函式

class C {
public:
	C(char* p) { m_p = p; }; 
	C& operator=(const C &str);
	char* m_p;
};

//answer
C& C::operator = (const C & str) {
//返回值取引用,並且函式結束時返回*this,使得可以連續賦值,如a = b = c;
//傳參為常量引用,避免呼叫賦值函式。
	if (this == &str)//檢測例項
		return *this
; delete[] m_p;//釋放自身記憶體 m_p = NULL; m_p = new char[strlen(str.m_p) + 1]; strcpy_s(m_p, strlen(str.m_p) + 1, str.m_p); return *this; } //高階解法: C& C::operator =(const C &str) { if (this != &str) { C strC(str);//區域性變數,自動析構。 char* p = strC.m_p; strC.m_p = m_p;//指向原來的地址,函式結束後釋放 m_p =
p;//先new後delete } return *this; }

二維陣列查詢

題目描述

在一個二維陣列中(每個一維陣列的長度相同),每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函式,輸入這樣的一個二維陣列和一個整數,判斷陣列中是否含有該整數。

//思路:二維的話,左上角最小,右下角最大,那麼在左下角開始判斷+移動,可以避免漏掉元素。
class Solution {
public:
    bool Find(int target, vector<vector<int> > array) {
        int
x = array.size(); int y = array[0].size(); int i = 0; int j = y-1; while(i < x && j>=0){ if(target < array[i][j]){ j--; }else if(target > array[i][j]){ i++; }else return true; } return false; } }; //題外: vector<vector<int>> a(9); for(i...9) a[i].resize(9); // 初始化/重設大小。 當然,初始化之後才可迭代 for(vector<vector<int>>::iterator i = array.begin();;) for(vector<int>::iterator j = (*i).begin();;) j[8];//好麻煩感覺hh a[7][8];//也可這樣訪問

替換空格

題目描述

請實現一個函式,將一個字串中的每個空格替換成“%20”。例如,當字串為We Are Happy.則經過替換之後的字串為We%20Are%20Happy。

class Solution {
public:
	void replaceSpace(char *str,int length) {

        
        string b = "";
        for(int i = 0; *(str+i) != '\0'; i++){
            if(*(str+i) == ' '){
                b = b + "%20";
            }else{
                b = b + *(str+i);
            }
        }
        strcpy(str, b.c_str());
	}
};


//題外
關於指標初始化問題:

char *p = “hello”;//error
//字串常量"hello"出現在一個表示式中時,"hello"表示式使用的值就是這些字元所儲存的地址(在常量區),
//而不是這些字元本身。可以把字串賦值給指向字元的指標p,而不能把字串賦值給一個字元陣列。 

char tmp[] = { "ggg" };
char* src = tmp;
*(src + 2) = '6';
//如此,為字串開闢新空間,便能修改

從尾到頭列印連結串列

題目描述

輸入一個連結串列,按連結串列值從尾到頭的順序返回一個ArrayList

/**
*  struct ListNode {
*        int val;
*        struct ListNode *next;
*        ListNode(int x) :
*              val(x), next(NULL) {
*        }
*  };
*/
class Solution {
public:
    vector<int> printListFromTailToHead(ListNode* head) {
        vector<int> i;
        stack<struct ListNode*> stk;
        while(head != NULL){
            stk.push(head);
            head = head->next;
        }
        
        while(!stk.empty()){
            head = stk.top();
            i.push_back(head->val);
            stk.pop();
        }
        return i;
    }
};


//使用遞迴(連結串列太長會爆棧)
if not null....
printListFromTailToHead(head->next);
printf(head->val);

重建二叉樹

題目描述

輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        vector<int> preL, preR, vinL, vinR;
        int len = pre.size();
        if(len == 0){
            return NULL;
        }
        struct TreeNode* head = new TreeNode(pre[0]);
        int index = 0;//index:目前root在vin中位置
        
        for(int i = 0; i < len; i++){
            if(vin[i] == pre[0]){
                index = i;
                break;
            }
        }
        
        for(int i = 0 ; i < index; i++){
            preL.push_back(pre[i+1]);
            vinL.push_back(vin[i]);
        }
        for(int i = index+1; i < len; i++){
            preR.push_back(pre[i]);
            vinR.push_back(vin[i]);
        }
        
        head->left = reConstructBinaryTree(preL, vinL);
        head->right = reConstructBinaryTree(preR, vinR);
        return head;
    }
};

.用於訪問類物件
->用於訪問指標物件

用兩個棧實現佇列

題目描述

用兩個棧來實現一個佇列,完成佇列的Push和Pop操作。 佇列中的元素為int型別。

class Solution{
public:
    void push(int node) {
        stack1.push(node);
    }

    int pop() {
        while(!stack1.empty()){
            stack2.push(stack1.top());
            stack1.pop();
        }//pop to stack2 until size==1
        int top = stack2.top();
        stack2.pop();
        
        while(!stack2.empty()){
            stack1.push(stack2.top());
            stack2.pop();
        }
        return top;
    }

private:
    stack<int> stack1;
    stack<int> stack2;
};


//時間複雜度低一點的
class Solution{
public:
    void push(int node) {
        stack1.push(node);
    }

    int pop() {
    	if(stack2.size() <= 0){//stack2(queue元素的正向排列)沒取完就不用取stack1的
			while(stack1.size() > 0){
				int n = stack1.top();
				stack1.top();
				stack2.push(n);
			}
		}

		if(stack2.size() == 0){
			throw new exception("queue empty");
		}

		int t = stack2.top();
		stack2.pop();
		return t;
    }

private:
    stack<int> stack1;
    stack<int> stack2;
};

旋轉陣列的最小數字

題目描述

把一個數組最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。 輸入一個非減排序的陣列的一個旋轉,輸出旋轉陣列的最小元素。 例如陣列{3,4,5,1,2}為{1,2,3,4,5}的一個旋轉,該陣列的最小值為1。 NOTE:給出的所有元素都大於0,若陣列大小為0,請返回0。

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        int len = rotateArray.size();
        if(len == 0)
            return 0;
        if(len == 1)
        	return rotateArray[0];
        int mid = 0;
        int l = 0;
        int r = len-1;
        while(rotateArray[l] >= rotateArray[r]){ // 非減序列,等號是個坑。。
            if(r-l == 1){
                mid = r;
                break;
            }
            mid = (l+r)/2;

			if(rotateArray[mid] == rotateArray[l] && rotateArray[mid] == rotateArray[r]){
				int mini = rotateArray[l];//解決如2221222,212222的例子
				for(int i = l+1; i < r; i++){
					if(mini > rotateArray[i])
						mini = rotateArray[i];
				}
				return mini;
			}

            //二分
            if(rotateArray[l] <= rotateArray[mid]){
                l = mid;
            }
            if(rotateArray[r] >= rotateArray[mid]){
                r = mid;
            }
        }
        return rotateArray[mid];
    }
};

連結串列中倒數第k個結點

題目描述

輸入一個連結串列,輸出該連結串列中倒數第k個結點。

//a先走k-1步,然後一起往前走,a到尾部的時候,k就是倒數第k位
class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
        ListNode* a = pListHead;
        ListNode* b = pListHead;
        if(a==NULL || k==0)//unsigned int k    k-1直接gg
            return NULL;
        for(int i = 0; i < k-1; i++){
            if(a->next==NULL)//注意如果k大於長度則NULL
                return NULL;
            a = a->next;
        }
        while(a->next != NULL){
            a = a->next;
            b = b->next;
        }
        return b;
    }
};

反轉連結串列

題目描述

輸入一個連結串列,反轉連結串列後,輸出新連結串列的表頭。

//魔性轉換
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        ListNode* pre = NULL;
        ListNode* next = NULL;
        while(pHead != NULL){
            next = pHead->next;
            pHead->next = pre;
            pre = pHead;
            pHead = next;
        }
        return pre;
    }
};

合併兩個排序的連結串列

題目描述

輸入兩個單調遞增的連結串列,輸出兩個連結串列合成後的連結串列,當然我們需要合成後的連結串列滿足單調不減規則。

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/

class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        if(pHead1 == NULL)
            return pHead2;
        if(pHead2 == NULL)
            return pHead1;
        ListNode* m = NULL;
        if(pHead1->val < pHead2->val){
            m = pHead1;
            m->next = Merge(pHead1->next, pHead2);
        }else{
            m = pHead2;
            m->next = Merge(pHead1, pHead2->next);
        }
        return m;
    }
};

//比較習慣非遞迴的
class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        if(pHead1 == NULL)
            return pHead2;
        if(pHead2 == NULL)
            return pHead1;
        ListNode* ans = NULL;
        ListNode* p = NULL;
        if (pHead1 > pHead2) {
            ans = p = pHead2;
            pHead2 = pHead2->next;
        }
        else {
            ans = p = pHead1;
            pHead1 = pHead1->next;
        }
        
        while (pHead1!=NULL && pHead2!=NULL) {
           if (pHead1->val > pHead2->val){
                p->next = pHead2;
                p = p->next;
                pHead2 = pHead2->next;
            }else {//h2>=h1
                p->next = pHead1;
                p = p->next;
                pHead1 = pHead1->next;
            }
        }
        if(pHead1 == NULL){
            p->next = pHead2;
        }else{
            p->next = pHead1;
        }
        return ans;
    }
};

樹的子結構

題目描述

輸入兩棵二叉樹A,B,判斷B是不是A的子結構。(ps:我們約定空樹不是任意一個樹的子結構)

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
    bool isSubTree(TreeNode* pRoot1, TreeNode* pRoot2){
        if(pRoot2 == NULL) return true;
        if(pRoot1 == NULL) return false;
        
        if(pRoot2->val == pRoot1->val){
            return isSubTree(pRoot1->left, pRoot2->left) &&
                    isSubTree(pRoot1->right, pRoot2->right);
        }
        return false;
    }
    
public:
    bool 
            
           

相關推薦

C++經驗

成員 cout 小數位 格式控制 flags point color 小數點 idt cout輸出流------格式控制符 他們在#include <iomanip>頭文件中 setprecision(n)與setiosflags(ios::fixed)合用,可

C記錄-1011

輸出 ++ main can pro clu 公約數 multipl panel 題目描述 輸入兩個正整數m和n,求其最大公約數和最小公倍數。 輸入 兩個整數 輸出 最大公約數,最小公倍數 樣例輸入 5 7 樣例輸出 1 35 1 #includ

C記錄-1014

for lld col 輸出 刷題 stdio.h panel 一個數 輸入 題目描述 求Sn=1!+2!+3!+4!+5!+…+n!之值,其中n是一個數字(n不超過20)。 輸入 n 輸出 Sn的值 樣例輸入 5 樣例輸出 153

C記錄-1015

code 1.0 輸入 urn printf clas sam 記錄 rec 題目描述 求以下三數的和,保留2位小數 1~a之和 1~b的平方和 1~c的倒數和 輸入 a b c 輸出 1+2+...+a + 1^2+2^2+...+b^2 + 1/1+1/2+.

C記錄-1017

amp math.h data span sample ane == can 刷題記錄 題目描述 一個數如果恰好等於不包含它本身所有因子之和,這個數就稱為"完數"。 例如,6的因子為1、2、3,而6=1+2+3,因此6是"完數"。 編程序找出N之內的所有完數,並按下面格

C記錄-1019

++ pri 每次 三次 n) += for nbsp 高度 題目描述 一球從M米高度自由下落,每次落地後返回原高度的一半,再落下。 它在第N次落地時反彈多高?共經過多少米? 保留兩位小數 輸入 M N 輸出 它在第N次落地時反彈多高?共經過多少米? 保留兩位小數

c++(3/100)數獨,棧和隊列

彈出 iter char col 編寫 實現 滑動窗口 title 表示 stack的基本操作 ? s.size():返回棧中的元素數量 ? s.empty():判斷棧是否為空,返回true或false ? s.push(元素):返回對棧頂部“元素”的可變(可修改)引用 ?

c++(15/100)矩陣轉置,最深子樹

標記 i++ con 結果 最短 網上 矩陣的轉置 alloc tree 題目一:矩陣轉置 給定一個矩陣 A, 返回 A 的轉置矩陣。 矩陣的轉置是指將矩陣的主對角線翻轉,交換矩陣的行索引與列索引。 示例 1: 輸入:[[1,2,3],[4,5,6],[7,8,9]]

c++(21/100)樹的打印、矩陣覆蓋和括號生成

生成 一個 ring 第一個 pop 全局 over 矩形 node 題目一:把二叉樹打印成多行 從上到下按層打印二叉樹,同一層結點從左至右輸出。每一層輸出一行。 思路:一開始以為2維的vector可以直接訪問,但是試了是不行,會報錯,vector在有值之前不能直接訪問,所

10-29C/C++

1、函式呼叫exec((v1,v2),(v3,v4,v5),v6,v7)中,實參的個數是4個。 解析:逗號運算子(百度百科):在C語言中,多個表示式可以用逗號分開,其中用逗號分開的表示式的值分別結算,但整個表示式的值是最後一個表示式的值。 所以exec((v1,v2), (v3,v4,v5)

10-22C/C++

1、有以下程式(strcpy 為字串賦值函式,strcat為字串連線函式) #include <stdio.h> #include <string.h> main() { char a[10]="abc",b[10]="012",c[10]="xyz"

11-1C/C++

1、對於以下程式碼: char *p=new char[100] p在棧上 new出來的在堆上 動態分配在堆中,其他的記憶體分配都在棧上進行。 2、static char a[2]={‘1’,‘2’,‘3’};說法是都正確? 錯誤 陣列越界 3、在C語言的定義和呼叫中,函式的定義不

C++

劍指Offer系列 賦值運算子函式 描述 為Class新增賦值運算子函式 class C { public: C(char* p) { m_p = p; }; C& operator=(const C &str); char* m_p; }; //a

C++萬能標頭檔案

最近做題發現了一個C++的萬能標頭檔案:#include <bits/stdc++.h> #include <bits/stdc++.h>包含了目前c++所包含的所有標頭檔案!!! 例如: #include<bits/stdc++.h>

C++記錄之:集合union

前言 好久沒有寫C語言的題目了,畢竟現在在學習資料結構,還是要練習c++的,上課的時候老師提到一個萬能標頭檔案#include<bits/stdc++.h> 今天在一個平臺練習C語言的時候正好使用這個檔案頭,感覺挺輕鬆的,省去很多標頭檔案,接下來對題目進行簡單的分析。 題目描述:集合union

c++ 檔案檢視器(有格式遍歷輸出資料夾目錄)

主要思路:每一層都先有符號標記再遞迴 #include <iostream> #include <sys/types.h> #include <dirent.h> #include <sys/stat.h> #in

c++

1、百度面試題之給定數字字串轉為相應數字。如“987”轉為987。 程式碼: #include<iostream> #include<typeinfo> using namespace std; int str2num(string str) {

C++常用

INT_MAX, INT_MIN atoi atoi(s.substr(0,2).to_str()) heap、make_heap、pop_heap、push_heap sort sort(a

國內C/C++網站彙總

- Welcome To PKU JudgeOnline 北京大學的Online Judge。POJ上面的題目有點老了,但好處是做的人多,經典演算法題多,解題報告也多,適合上手。 - ZOJ : Home 浙江大學的Online Judge。ZOJ用的不多,但為數不多的幾次體驗好像都還可以,值得嘗試。 - W

C++——1923: ASCII碼排序

題目描述 輸入三個字元後,按各字元的ASCII碼從小到大的順序輸出這三個字元。 輸入 輸入資料有多組,每組佔一行,有三個字元組成,之間無空格。 輸出 方法一: 對於每組輸入資料,輸出一行,字元中間用一個空格分開。 #include <iostream> #in