C++笔记——自定义函数

1、定义 Perm–全排列函数
代码如下:

    void Perm(int* arr,int size,int N)  
    {  
     if(size == N)  
     {  
       for(size_t i=0;i<size;++i)  
           cout<<arr[i];  
       cout<<endl;  
     }  
     else  
     {  
       for(size_t i=N;i<size;++i)  
       {  
           std::swap(arr[i],arr[N]);  
           Perm(arr,size,N+1);  
           std::swap(arr[i],arr[N]);  
       }  
     }  
    }  

详细解释:
例如传入arr 数组为12345
(1)Perm(arr,5,3):表示arr数组的下标为3的开始全排列,即45全排列。
输出:12345 12354
(2)Perm(arr,5,2):表示arr的后3位全排列。即345全排列。
输出:12345 12354 12435 12453 12543 12534
(3)Perm(arr,5,0):表示arr数组全排列。此处验证省略。可自行验证。
时间复杂度为:N+N*(N-1)+N*(N-1)(N-2)+………..+1
约等于 O(N!)
以下代码可用于带重复元素的全排列:

#include<stdio.h>
#include<malloc.h>

int len;
int count = 0;
void swap(int *a, int *b)
{
    int tem;
    tem = *a;
    *a = *b;
    *b = tem;
}

bool clap(int * ar, int be, int en)
{
    if(en > be)
    {
        for(int i = be; i < en; i++)
        {
            if(ar[i] == ar[en])
                return false;
        }
    }
    return true;
}

void fullypai(int * arr, int beg, int end)
{
    if (beg == end)
    {
        for(int i = 0; i < len; i++)
        {
            printf("%d ", arr[i]);
        }
        printf("\n");
        ++count;
    }
    else
    {
        for(int i = beg; i < end; i++)
        {
            if(clap(arr, beg, i))
            {
                swap(arr+beg, arr+i);
                fullypai(arr, beg+1, end);
                swap(arr+beg, arr+i);
            }
        }
    }
}

int main()
{
    printf("please input a number len and an array include len element:\n");
    scanf("%d\n", &len);
    int * array = (int *)malloc(sizeof(int) * len);

    for(int i = 0; i < len; i++)
    {
        scanf("%d", &array[i]);
    }
    printf("\n");
    fullypai(array, 0, len);
    printf("totle:%d\n",count);
    return 0;
}

2、从0到n-1中随机等概率输出m个不重复的数

void knuth(int n,int m)
{
  srand((unsigned int)time(0));
  for(int i = 0;i<n;i++)
  {
    if(rand()%(n-i)<m)
    {
      cout<<i<<endl;
      m--;
    }
  }
}

思路解析
for循环执行了n次,每次输出不同的i值,总共满足条件的i值有m个,因此,m个不重复的数的要求已达到。
下面考虑如何等概率?
i=0时,rand()%(n-i)取值范围为0-n-1,共计n个数,此时如果输出0,只需要rand()%(n-i)小于m,因此,i=0被输出的概率为m/n
i=1时,rand()%(n-i)取值范围为0-n-2,共计n-1个数,此时如果0已经输出了,则m已经自减,此时为m-1,则i=1被输出的概率为(m-1)/(n-1);如果0没有被输出,则m未自减,此时,i=1被输出的概率为m/(n-1)。此时,i=1被输出的概率为(1-m/n)x(m/(n-1))+m/nx(m-1)/(n-1)=m/n。
依次类推,每个数被输出的概率都是m/n。
3、二分法查找元素

#include<iostream>
#include<algorithm>
using namespace std;
int find(int list[], int ele, int length)
{
    const int s = 0;
    const int e = length;
    int start = s;
    int end = e;
    while(start <= end)
    {
        int tem = (start+end)/2;
        if(list[tem] == ele)
        {
            cout << "The element is in the list" << endl;
            return 1;
        }
        if(list[tem] > ele)
        {
            end = tem-1;
        }
        if(list[tem] < ele)
        {
            start = tem+1;
        }
    }
    cout << "The element is not in the list" << endl;
    return 1;
}
int main()
{
    int a[4] = {2, 8, 5, 7};
    int len = sizeof(a)/sizeof(a[1]);
    int x;
    cin >> x;
    sort(a, a+4);
    find(a, x, len);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++ 中,我们可以使用串口类来进行串口通信。这里我们将自定义一个串口类,以便更好地理解串口通信的原理和实现。 首先,我们需要引入一些头文件: ```c++ #include <windows.h> #include <iostream> ``` 接着,我们定义一个串口类,其中包含了串口的打开、关闭、读取和写入等操作: ```c++ class SerialPort { public: SerialPort(); ~SerialPort(); bool Open(int portNo, int baudRate); bool Close(); int ReadData(char *buffer, unsigned int nbChar); bool WriteData(char *buffer, unsigned int nbChar); bool IsOpened() const; private: HANDLE m_hComm; bool m_bOpened; }; ``` 其中,m_hComm 是串口的句柄,m_bOpened 表示串口是否打开。 接下来,我们来实现这些操作。 首先是串口的打开操作: ```c++ bool SerialPort::Open(int portNo, int baudRate) { if (m_bOpened) { Close(); } char portName[50]; sprintf_s(portName, "\\\\.\\COM%d", portNo); m_hComm = CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr); if (m_hComm == INVALID_HANDLE_VALUE) { std::cerr << "Failed to open serial port!\n"; return false; } DCB dcb; GetCommState(m_hComm, &dcb); dcb.BaudRate = baudRate; dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; if (!SetCommState(m_hComm, &dcb)) { std::cerr << "Failed to set serial port parameters!\n"; CloseHandle(m_hComm); return false; } m_bOpened = true; return true; } ``` 这里我们首先判断串口是否已经打开,如果已经打开则先关闭,然后根据串口号构建串口名称,并使用 CreateFile 函数打开串口。接着,我们设置串口的参数,包括波特率、数据位、校验位和停止位等。如果设置成功,则将 m_bOpened 设置为 true 并返回 true,否则返回 false。 接下来是串口的关闭操作: ```c++ bool SerialPort::Close() { if (!m_bOpened) { return true; } if (CloseHandle(m_hComm)) { m_bOpened = false; return true; } return false; } ``` 这里我们只需要调用 CloseHandle 函数关闭串口,并将 m_bOpened 设置为 false 即可。 接下来是串口的读取操作: ```c++ int SerialPort::ReadData(char *buffer, unsigned int nbChar) { DWORD bytesRead; if (!ReadFile(m_hComm, buffer, nbChar, &bytesRead, nullptr)) { std::cerr << "Failed to read data from serial port!\n"; return -1; } return bytesRead; } ``` 这里我们使用 ReadFile 函数从串口读取数据,并将读取的字节数存储在 bytesRead 变量中,并返回 bytesRead。 最后是串口的写入操作: ```c++ bool SerialPort::WriteData(char *buffer, unsigned int nbChar) { DWORD bytesSent; if (!WriteFile(m_hComm, buffer, nbChar, &bytesSent, nullptr)) { std::cerr << "Failed to write data to serial port!\n"; return false; } return true; } ``` 这里我们使用 WriteFile 函数将数据写入串口,并返回写入是否成功的结果。 最后,我们来实现一个判断串口是否打开的函数: ```c++ bool SerialPort::IsOpened() const { return m_bOpened; } ``` 这里只需要返回 m_bOpened 即可。 至此,我们就完成了一个简单的自定义串口类。可以通过实例化这个类来进行串口通信的操作,具体使用方法可以参考下面的示例代码: ```c++ int main() { SerialPort port; if (!port.Open(1, 9600)) { return -1; } char buffer[1024]; while (true) { int bytesRead = port.ReadData(buffer, sizeof(buffer)); if (bytesRead > 0) { buffer[bytesRead] = '\0'; std::cout << buffer << std::endl; } } port.Close(); return 0; } ``` 在这个示例中,我们首先实例化了一个 SerialPort 类,并通过 Open 函数打开了 COM1 号串口。然后,我们通过 ReadData 函数从串口读取数据,并将读取的数据打印到控制台上。最后,我们通过 Close 函数关闭了串口。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值