欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++?OpenCV實(shí)現(xiàn)之實(shí)現(xiàn)紅綠燈識別

 更新時(shí)間:2022年08月02日 10:03:27   作者:猿力豬  
本文以實(shí)現(xiàn)行車過程當(dāng)中的紅綠燈識別為目標(biāo),核心的內(nèi)容包括:OpenCV輪廓識別原理以及OpenCV紅綠燈識別的實(shí)現(xiàn)具體步驟,感興趣的可以了解一下

前言

本文以實(shí)現(xiàn)行車過程當(dāng)中的紅綠燈識別為目標(biāo),核心的內(nèi)容包括:OpenCV輪廓識別原理以及OpenCV紅綠燈識別的實(shí)現(xiàn)具體步驟

一、輪廓識別相關(guān)原理

什么是輪廓檢測

目前輪廓檢測方法有兩類,一類是利用傳統(tǒng)的邊緣檢測算子檢測目標(biāo)輪廓,另一類是從人類視覺系統(tǒng)中提取可以使用的數(shù)學(xué)模型完成目標(biāo)輪廓檢測

輪廓提取函數(shù)findContours

函數(shù)原型: 

findContours( InputOutputArray image, OutputArrayOfArrays contours,
                              OutputArray hierarchy, int mode,
                              int method, Point offset=Point());

參數(shù):

image:單通道圖像矩陣,可以是灰度圖,但更常用的是二值圖像,一般是經(jīng)過Canny、拉普拉斯等邊緣檢測算子處理過的二值圖像

contours:  定義為“vector<vector<Point>> contours”,是一個(gè)向量,并且是一個(gè)雙重向量,向量內(nèi)每個(gè)元素保存了一組由連續(xù)的Point點(diǎn)構(gòu)成的點(diǎn)的集合的向量,每一組Point點(diǎn)集就是一個(gè)輪廓。有多少輪廓,向量contours就有多少元素

hierarchy:  也是一個(gè)向量,向量內(nèi)每個(gè)元素保存了一個(gè)包含4個(gè)int整型的數(shù)組。向量內(nèi)的元素和輪廓向量contours內(nèi)的元素是一一對應(yīng)的,向量的容量相同

int mode: 

取值一:CV_CHAIN_APPROX_NONE 保存物體邊界上所有連續(xù)的輪廓點(diǎn)到 contours向量內(nèi)

取值二:CV_CHAIN_APPROX_SIMPLE 僅保存輪廓的拐點(diǎn)信息,把所有輪廓拐點(diǎn)處的點(diǎn)保存入contours向量內(nèi),拐點(diǎn)與拐點(diǎn)之間直線段上的信息點(diǎn)不予保留

取值三和四:CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法

Point: Point偏移量,所有的輪廓信息相對于原始圖像對應(yīng)點(diǎn)的偏移量,相當(dāng)于在每一個(gè)檢測出的輪廓點(diǎn)上加上該偏移量,并且Point還可以是負(fù)值!

參數(shù)詳解引用出處:findContours函數(shù)參數(shù)詳解

二、案例實(shí)現(xiàn)

這是本案例所用到的素材,如下圖所示: 

PS:視頻的效果比較好,如果方便的話可以自行外出拍攝取材

Step1:初始化配置

做好準(zhǔn)備工作,創(chuàng)建我們需要的內(nèi)容,設(shè)置亮度參數(shù),以及我們導(dǎo)入的視頻路徑

    int redCount = 0;
    int greenCount = 0;
 
    Mat frame;
    Mat img;
    Mat imgYCrCb;
    Mat imgGreen;
    Mat imgRed;
 
    // 亮度參數(shù)
    double a = 0.3;
    double b = (1 - a) * 125;
 
    VideoCapture capture("C:/Users/86177/Desktop/image/123.mp4");//導(dǎo)入視頻的路徑
    if (!capture.isOpened())
    {
        cout << "Start device failed!\n" << endl;//啟動(dòng)設(shè)備失??!
        return -1;
    }

Step2:進(jìn)行幀處理

調(diào)整視頻亮度,分解YCrCb的三個(gè)成分,拆分紅色和綠色,方便對紅綠兩種顏色進(jìn)行特征提取

    // 幀處理
    while (1)
    {
        capture >> frame;
        //調(diào)整亮度
        frame.convertTo(img, img.type(), a, b);
 
        //轉(zhuǎn)換為YCrCb顏色空間
        cvtColor(img, imgYCrCb, CV_BGR2YCrCb);
 
        imgRed.create(imgYCrCb.rows, imgYCrCb.cols, CV_8UC1);
        imgGreen.create(imgYCrCb.rows, imgYCrCb.cols, CV_8UC1);
 
        //分解YCrCb的三個(gè)成分
        vector<Mat> planes;
        split(imgYCrCb, planes);
        // 遍歷以根據(jù)Cr分量拆分紅色和綠色
        MatIterator_<uchar> it_Cr = planes[1].begin<uchar>(),
                it_Cr_end = planes[1].end<uchar>();
        MatIterator_<uchar> it_Red = imgRed.begin<uchar>();
        MatIterator_<uchar> it_Green = imgGreen.begin<uchar>();
 
        for (; it_Cr != it_Cr_end; ++it_Cr, ++it_Red, ++it_Green)
        {
            // RED, 145<Cr<470 紅色
            if (*it_Cr > 145 && *it_Cr < 470)
                *it_Red = 255;
            else
                *it_Red = 0;
 
            // GREEN 95<Cr<110 綠色
            if (*it_Cr > 95 && *it_Cr < 110)
                *it_Green = 255;
            else
                *it_Green = 0;
        }

Step3:膨脹腐蝕處理

去除其他噪點(diǎn),提高我們需要的紅綠燈的特征

        //膨脹和腐蝕
        dilate(imgRed, imgRed, Mat(15, 15, CV_8UC1), Point(-1, -1));
        erode(imgRed, imgRed, Mat(1, 1, CV_8UC1), Point(-1, -1));
        dilate(imgGreen, imgGreen, Mat(15, 15, CV_8UC1), Point(-1, -1));
        erode(imgGreen, imgGreen, Mat(1, 1, CV_8UC1), Point(-1, -1));
 
        redCount = processImgR(imgRed);
        greenCount = processImgG(imgGreen);
        cout << "red:" << redCount << ";  " << "green:" << greenCount << endl;

Step4:紅綠燈提示判斷

加入紅綠燈識別結(jié)果顯示,方便我們查看效果

        if(redCount == 0 && greenCount == 0)
        {
            cv::putText(frame, "lights out", Point(40, 150), cv::FONT_HERSHEY_SIMPLEX, 2, cv::Scalar(255, 255, 255), 8, 8, 0);
        }else if(redCount > greenCount)
        {
            cv::putText(frame, "red light", Point(40, 150), cv::FONT_HERSHEY_SIMPLEX, 2, cv::Scalar(0, 0, 255), 8, 8, 0);
        }else{
            cv::putText(frame, "green light", Point(40, 150), cv::FONT_HERSHEY_SIMPLEX, 2, cv::Scalar(0, 255, 0), 8, 8, 0);
        }

Step5:輪廓提取

分別對紅燈和綠燈進(jìn)行輪廓特征提取,提高辨識度

int processImgR(Mat src)
{
    Mat tmp;
 
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    vector<Point> hull;
 
    CvPoint2D32f tempNode;
    CvMemStorage* storage = cvCreateMemStorage();
    CvSeq* pointSeq = cvCreateSeq(CV_32FC2, sizeof(CvSeq), sizeof(CvPoint2D32f), storage);
 
    Rect* trackBox;
    Rect* result;
    int resultNum = 0;
 
    int area = 0;
    src.copyTo(tmp);
 
    //提取輪廓
    findContours(tmp, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
 
    if (contours.size() > 0)
    {
        trackBox = new Rect[contours.size()];
        result = new Rect[contours.size()];
 
        //確定要跟蹤的區(qū)域
        for (int i = 0; i < contours.size(); i++)
        {
            cvClearSeq(pointSeq);
            // 獲取凸包的點(diǎn)集
            convexHull(Mat(contours[i]), hull, true);
            int hullcount = (int)hull.size();
            // 凸包的保存點(diǎn)
            for (int j = 0; j < hullcount - 1; j++)
            {
                tempNode.x = hull[j].x;
                tempNode.y = hull[j].y;
                cvSeqPush(pointSeq, &tempNode);
            }
 
            trackBox[i] = cvBoundingRect(pointSeq);
        }
 
        if (isFirstDetectedR)
        {
            lastTrackBoxR = new Rect[contours.size()];
            for (int i = 0; i < contours.size(); i++)
                lastTrackBoxR[i] = trackBox[i];
            lastTrackNumR = contours.size();
            isFirstDetectedR = false;
        }
        else
        {
            for (int i = 0; i < contours.size(); i++)
            {
                for (int j = 0; j < lastTrackNumR; j++)
                {
                    if (isIntersected(trackBox[i], lastTrackBoxR[j]))
                    {
                        result[resultNum] = trackBox[i];
                        break;
                    }
                }
                resultNum++;
            }
            delete[] lastTrackBoxR;
            lastTrackBoxR = new Rect[contours.size()];
            for (int i = 0; i < contours.size(); i++)
            {
                lastTrackBoxR[i] = trackBox[i];
            }
            lastTrackNumR = contours.size();
        }
 
        delete[] trackBox;
    }
    else
    {
        isFirstDetectedR = true;
        result = NULL;
    }
    cvReleaseMemStorage(&storage);
 
    if (result != NULL)
    {
        for (int i = 0; i < resultNum; i++)
        {
            area += result[i].area();
        }
    }
    delete[] result;
 
    return area;
}
 
int processImgG(Mat src)
{
    Mat tmp;
 
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    vector< Point > hull;
 
    CvPoint2D32f tempNode;
    CvMemStorage* storage = cvCreateMemStorage();
    CvSeq* pointSeq = cvCreateSeq(CV_32FC2, sizeof(CvSeq), sizeof(CvPoint2D32f), storage);
 
    Rect* trackBox;
    Rect* result;
    int resultNum = 0;
 
    int area = 0;
 
    src.copyTo(tmp);
    //提取輪廓
    findContours(tmp, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
 
    if (contours.size() > 0)
    {
        trackBox = new Rect[contours.size()];
        result = new Rect[contours.size()];
 
        // 確定要跟蹤的區(qū)域
        for (int i = 0; i < contours.size(); i++)
        {
            cvClearSeq(pointSeq);
            // 獲取凸包的點(diǎn)集
            convexHull(Mat(contours[i]), hull, true);
            int hullcount = (int)hull.size();
            // 保存凸包的點(diǎn)
            for (int j = 0; j < hullcount - 1; j++)
            {
                tempNode.x = hull[j].x;
                tempNode.y = hull[j].y;
                cvSeqPush(pointSeq, &tempNode);
            }
 
            trackBox[i] = cvBoundingRect(pointSeq);
        }
 
        if (isFirstDetectedG)
        {
            lastTrackBoxG = new Rect[contours.size()];
            for (int i = 0; i < contours.size(); i++)
                lastTrackBoxG[i] = trackBox[i];
            lastTrackNumG = contours.size();
            isFirstDetectedG = false;
        }
        else
        {
            for (int i = 0; i < contours.size(); i++)
            {
                for (int j = 0; j < lastTrackNumG; j++)
                {
                    if (isIntersected(trackBox[i], lastTrackBoxG[j]))
                    {
                        result[resultNum] = trackBox[i];
                        break;
                    }
                }
                resultNum++;
            }
            delete[] lastTrackBoxG;
            lastTrackBoxG = new Rect[contours.size()];
            for (int i = 0; i < contours.size(); i++)
            {
                lastTrackBoxG[i] = trackBox[i];
            }
            lastTrackNumG = contours.size();
        }
 
        delete[] trackBox;
    }
    else
    {
        isFirstDetectedG = true;
        result = NULL;
    }
    cvReleaseMemStorage(&storage);
 
    if (result != NULL)
    {
        for (int i = 0; i < resultNum; i++)
        {
            area += result[i].area();
        }
    }
    delete[] result;
 
    return area;
}

Step6:判斷是否相交

//確定兩個(gè)矩形區(qū)域是否相交
bool isIntersected(Rect r1, Rect r2)
{
    int minX = max(r1.x, r2.x);
    int minY = max(r1.y, r2.y);
    int maxX = min(r1.x + r1.width, r2.x + r2.width);
    int maxY = min(r1.y + r1.height, r2.y + r2.height);
 
    if (minX < maxX && minY < maxY)
        return true;
    else
        return false;
}

案例效果

完整代碼

#include "opencv2/opencv.hpp"
#include "opencv2/imgproc.hpp"
#include <windows.h>
#include <iostream>
 
using namespace std;
using namespace cv;
 
// Function headers
int processImgR(Mat);
int processImgG(Mat);
bool isIntersected(Rect, Rect);
 
// Global variables
bool isFirstDetectedR = true;
bool isFirstDetectedG = true;
Rect* lastTrackBoxR;
Rect* lastTrackBoxG;
int lastTrackNumR;
int lastTrackNumG;
 
//主函數(shù)
int main()
{
    int redCount = 0;
    int greenCount = 0;
 
    Mat frame;
    Mat img;
    Mat imgYCrCb;
    Mat imgGreen;
    Mat imgRed;
 
    // 亮度參數(shù)
    double a = 0.3;
    double b = (1 - a) * 125;
 
    VideoCapture capture("C:/Users/86177/Desktop/image/123.mp4");//導(dǎo)入視頻的路徑
    if (!capture.isOpened())
    {
        cout << "Start device failed!\n" << endl;//啟動(dòng)設(shè)備失??!
        return -1;
    }
 
    // 幀處理
    while (1)
    {
        capture >> frame;
        //調(diào)整亮度
        frame.convertTo(img, img.type(), a, b);
 
        //轉(zhuǎn)換為YCrCb顏色空間
        cvtColor(img, imgYCrCb, CV_BGR2YCrCb);
 
        imgRed.create(imgYCrCb.rows, imgYCrCb.cols, CV_8UC1);
        imgGreen.create(imgYCrCb.rows, imgYCrCb.cols, CV_8UC1);
 
        //分解YCrCb的三個(gè)成分
        vector<Mat> planes;
        split(imgYCrCb, planes);
        // 遍歷以根據(jù)Cr分量拆分紅色和綠色
        MatIterator_<uchar> it_Cr = planes[1].begin<uchar>(),
                it_Cr_end = planes[1].end<uchar>();
        MatIterator_<uchar> it_Red = imgRed.begin<uchar>();
        MatIterator_<uchar> it_Green = imgGreen.begin<uchar>();
 
        for (; it_Cr != it_Cr_end; ++it_Cr, ++it_Red, ++it_Green)
        {
            // RED, 145<Cr<470 紅色
            if (*it_Cr > 145 && *it_Cr < 470)
                *it_Red = 255;
            else
                *it_Red = 0;
 
            // GREEN 95<Cr<110 綠色
            if (*it_Cr > 95 && *it_Cr < 110)
                *it_Green = 255;
            else
                *it_Green = 0;
        }
 
        //膨脹和腐蝕
        dilate(imgRed, imgRed, Mat(15, 15, CV_8UC1), Point(-1, -1));
        erode(imgRed, imgRed, Mat(1, 1, CV_8UC1), Point(-1, -1));
        dilate(imgGreen, imgGreen, Mat(15, 15, CV_8UC1), Point(-1, -1));
        erode(imgGreen, imgGreen, Mat(1, 1, CV_8UC1), Point(-1, -1));
 
        redCount = processImgR(imgRed);
        greenCount = processImgG(imgGreen);
        cout << "red:" << redCount << ";  " << "green:" << greenCount << endl;
 
        if(redCount == 0 && greenCount == 0)
        {
            cv::putText(frame, "lights out", Point(40, 150), cv::FONT_HERSHEY_SIMPLEX, 2, cv::Scalar(255, 255, 255), 8, 8, 0);
        }else if(redCount > greenCount)
        {
            cv::putText(frame, "red light", Point(40, 150), cv::FONT_HERSHEY_SIMPLEX, 2, cv::Scalar(0, 0, 255), 8, 8, 0);
        }else{
            cv::putText(frame, "green light", Point(40, 150), cv::FONT_HERSHEY_SIMPLEX, 2, cv::Scalar(0, 255, 0), 8, 8, 0);
        }
 
        imshow("video", frame);
        imshow("Red", imgRed);
        imshow("Green", imgGreen);
 
        // Handle with the keyboard input
        if (cvWaitKey(20) == 'q')
            break;
    }
 
    return 0;
}
 
int processImgR(Mat src)
{
    Mat tmp;
 
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    vector<Point> hull;
 
    CvPoint2D32f tempNode;
    CvMemStorage* storage = cvCreateMemStorage();
    CvSeq* pointSeq = cvCreateSeq(CV_32FC2, sizeof(CvSeq), sizeof(CvPoint2D32f), storage);
 
    Rect* trackBox;
    Rect* result;
    int resultNum = 0;
 
    int area = 0;
    src.copyTo(tmp);
 
    //提取輪廓
    findContours(tmp, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
 
    if (contours.size() > 0)
    {
        trackBox = new Rect[contours.size()];
        result = new Rect[contours.size()];
 
        //確定要跟蹤的區(qū)域
        for (int i = 0; i < contours.size(); i++)
        {
            cvClearSeq(pointSeq);
            // 獲取凸包的點(diǎn)集
            convexHull(Mat(contours[i]), hull, true);
            int hullcount = (int)hull.size();
            // 凸包的保存點(diǎn)
            for (int j = 0; j < hullcount - 1; j++)
            {
                tempNode.x = hull[j].x;
                tempNode.y = hull[j].y;
                cvSeqPush(pointSeq, &tempNode);
            }
 
            trackBox[i] = cvBoundingRect(pointSeq);
        }
 
        if (isFirstDetectedR)
        {
            lastTrackBoxR = new Rect[contours.size()];
            for (int i = 0; i < contours.size(); i++)
                lastTrackBoxR[i] = trackBox[i];
            lastTrackNumR = contours.size();
            isFirstDetectedR = false;
        }
        else
        {
            for (int i = 0; i < contours.size(); i++)
            {
                for (int j = 0; j < lastTrackNumR; j++)
                {
                    if (isIntersected(trackBox[i], lastTrackBoxR[j]))
                    {
                        result[resultNum] = trackBox[i];
                        break;
                    }
                }
                resultNum++;
            }
            delete[] lastTrackBoxR;
            lastTrackBoxR = new Rect[contours.size()];
            for (int i = 0; i < contours.size(); i++)
            {
                lastTrackBoxR[i] = trackBox[i];
            }
            lastTrackNumR = contours.size();
        }
 
        delete[] trackBox;
    }
    else
    {
        isFirstDetectedR = true;
        result = NULL;
    }
    cvReleaseMemStorage(&storage);
 
    if (result != NULL)
    {
        for (int i = 0; i < resultNum; i++)
        {
            area += result[i].area();
        }
    }
    delete[] result;
 
    return area;
}
 
int processImgG(Mat src)
{
    Mat tmp;
 
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    vector< Point > hull;
 
    CvPoint2D32f tempNode;
    CvMemStorage* storage = cvCreateMemStorage();
    CvSeq* pointSeq = cvCreateSeq(CV_32FC2, sizeof(CvSeq), sizeof(CvPoint2D32f), storage);
 
    Rect* trackBox;
    Rect* result;
    int resultNum = 0;
 
    int area = 0;
 
    src.copyTo(tmp);
    //提取輪廓
    findContours(tmp, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
 
    if (contours.size() > 0)
    {
        trackBox = new Rect[contours.size()];
        result = new Rect[contours.size()];
 
        // 確定要跟蹤的區(qū)域
        for (int i = 0; i < contours.size(); i++)
        {
            cvClearSeq(pointSeq);
            // 獲取凸包的點(diǎn)集
            convexHull(Mat(contours[i]), hull, true);
            int hullcount = (int)hull.size();
            // 保存凸包的點(diǎn)
            for (int j = 0; j < hullcount - 1; j++)
            {
                tempNode.x = hull[j].x;
                tempNode.y = hull[j].y;
                cvSeqPush(pointSeq, &tempNode);
            }
 
            trackBox[i] = cvBoundingRect(pointSeq);
        }
 
        if (isFirstDetectedG)
        {
            lastTrackBoxG = new Rect[contours.size()];
            for (int i = 0; i < contours.size(); i++)
                lastTrackBoxG[i] = trackBox[i];
            lastTrackNumG = contours.size();
            isFirstDetectedG = false;
        }
        else
        {
            for (int i = 0; i < contours.size(); i++)
            {
                for (int j = 0; j < lastTrackNumG; j++)
                {
                    if (isIntersected(trackBox[i], lastTrackBoxG[j]))
                    {
                        result[resultNum] = trackBox[i];
                        break;
                    }
                }
                resultNum++;
            }
            delete[] lastTrackBoxG;
            lastTrackBoxG = new Rect[contours.size()];
            for (int i = 0; i < contours.size(); i++)
            {
                lastTrackBoxG[i] = trackBox[i];
            }
            lastTrackNumG = contours.size();
        }
 
        delete[] trackBox;
    }
    else
    {
        isFirstDetectedG = true;
        result = NULL;
    }
    cvReleaseMemStorage(&storage);
 
    if (result != NULL)
    {
        for (int i = 0; i < resultNum; i++)
        {
            area += result[i].area();
        }
    }
    delete[] result;
 
    return area;
}
 
//確定兩個(gè)矩形區(qū)域是否相交
bool isIntersected(Rect r1, Rect r2)
{
    int minX = max(r1.x, r2.x);
    int minY = max(r1.y, r2.y);
    int maxX = min(r1.x + r1.width, r2.x + r2.width);
    int maxY = min(r1.y + r1.height, r2.y + r2.height);
 
    if (minX < maxX && minY < maxY)
        return true;
    else
        return false;
}

三、總結(jié)

本文主要講解OpenCV輪廓識別原理以及OpenCV紅綠燈識別的實(shí)現(xiàn)具體步驟OpenCV還是有很多識別的庫函數(shù)可以用,接下來繼續(xù)探索,結(jié)合生活實(shí)際繼續(xù)做一些有意思的案例

到此這篇關(guān)于C++ OpenCV實(shí)現(xiàn)之實(shí)現(xiàn)紅綠燈識別的文章就介紹到這了,更多相關(guān)C++ OpenCV紅綠燈識別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++中 set的用法

    C++中 set的用法

    這篇文章主要介紹了C++中 set的用法,set的內(nèi)部使用了紅黑樹對所有的元素進(jìn)行了排序。在樹結(jié)構(gòu)當(dāng)中,我們通常使用的都是<key, value>的形式。下面我們來看看該內(nèi)容的具體情況,需要的朋友也可以參考一下
    2021-11-11
  • MFC擴(kuò)展DLL中導(dǎo)出類和對話框的實(shí)現(xiàn)方法

    MFC擴(kuò)展DLL中導(dǎo)出類和對話框的實(shí)現(xiàn)方法

    這篇文章主要介紹了MFC擴(kuò)展DLL中導(dǎo)出類和對話框的實(shí)現(xiàn)方法,詳細(xì)講述了實(shí)現(xiàn)擴(kuò)展DLL中導(dǎo)出類和對話框的具體步驟與方法,具有不錯(cuò)的實(shí)用價(jià)值,需要的朋友可以參考下
    2014-10-10
  • 文件編譯時(shí)出現(xiàn)multiple definition of ''xxxxxx''的具體解決方法

    文件編譯時(shí)出現(xiàn)multiple definition of ''xxxxxx''的具體解決方法

    以下是對文件編譯時(shí)出現(xiàn)multiple definition of 'xxxxxx'的解決方法進(jìn)行了詳細(xì)的分析介紹,如也遇到此問題的朋友們可以過來參考下
    2013-07-07
  • C語言實(shí)現(xiàn)三子棋的步驟和代碼詳解

    C語言實(shí)現(xiàn)三子棋的步驟和代碼詳解

    這篇文章主要介紹了C語言實(shí)現(xiàn)三子棋的步驟和代碼詳解,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • C語言實(shí)現(xiàn)桶排序的方法示例

    C語言實(shí)現(xiàn)桶排序的方法示例

    這篇文章主要介紹了C語言實(shí)現(xiàn)桶排序的方法,簡單描述了桶排序的概念、原理并結(jié)合實(shí)例形式分析了C語言實(shí)現(xiàn)桶排序算法的具體操作技巧,需要的朋友可以參考下
    2018-01-01
  • C語言全方位講解指針與地址和數(shù)組函數(shù)堆空間的關(guān)系

    C語言全方位講解指針與地址和數(shù)組函數(shù)堆空間的關(guān)系

    指針是C語言中一個(gè)非常重要的概念,也是C語言的特色之一。使用指針可以對復(fù)雜數(shù)據(jù)進(jìn)行處理,能對計(jì)算機(jī)的內(nèi)存分配進(jìn)行控制,在函數(shù)調(diào)用中使用指針還可以返回多個(gè)值
    2022-04-04
  • C/C++實(shí)現(xiàn)快速排序的方法

    C/C++實(shí)現(xiàn)快速排序的方法

    這篇文章主要介紹了C/C++實(shí)現(xiàn)快速排序的方法,這幾天在找工作,被問到快速排序,結(jié)果想不出來快速排序怎么弄的;回來搜索了一下,現(xiàn)在記錄下來,方便以后查看。
    2014-12-12
  • C++11的for循環(huán)的新用法(推薦)

    C++11的for循環(huán)的新用法(推薦)

    C++11這次的更新帶來了令很多C++程序員期待已久的for range循環(huán),每次看到j(luò)avascript, lua里的for range,心想要是C++能有多好,心里別提多酸了。這次C++11不負(fù)眾望,再也不用羨慕別家人的for range了。下面看下C++11的for循環(huán)的新用法
    2021-11-11
  • C++數(shù)據(jù)結(jié)構(gòu)AVL樹全面分析

    C++數(shù)據(jù)結(jié)構(gòu)AVL樹全面分析

    今天的這一篇博客,我要跟大家介紹一顆樹——AVL樹,它也是一顆二叉搜索樹,它就是在二叉搜索樹中加了一個(gè)平衡因子的概念在里面,下面我就來和大家聊一聊這棵樹是個(gè)怎么樣的樹
    2021-10-10
  • c語言 漢諾塔算法代碼

    c語言 漢諾塔算法代碼

    c語言 漢諾塔算法代碼,需要的朋友可以參考一下
    2013-04-04

最新評論