2021-03-11

https://blog.csdn.net/qq_35034604/article/details/107959429?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-14.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-14.control

#include <iostream>
#include <vector>
#include "string"
using namespace std;
//构造一个二维数组
//对于一个子串而言,如果它是回文串,并且长度大于 22,那么将它首尾的两个字母去除之后,它仍然是个回文串。例如对于字符串ababa
//根据这样的思路,我们就可以用动态规划的方法解决本题。我们用 P(i,j)P(i,j) 表示字符串s的第 i 到 j 个字母组成的串(下文表示成 s[i:j]s[i:j])是否为回文串:
//P[i,j] = true,表示s[i]-s[j]是回文串.其他情况P[i,j] = false,这里其他情况表示s[i]-s[j]不是回文串或者s[i]到s[j]不合法
//动态规划的状态转移方程:P(i, j) = P(i+1, j-1) && (S[i] == S[j])
//也就是说,只有 s[i+1:j-1]是回文串,并且s[i]==s[j]时才是回文串。
//上文的所有讨论是建立在子串长度大于2,我们还需要考虑动态规划中的边界条件,即子串的长度为1或2。1或2拿出来单独判断。
//我们可以这么推导,P(i,i)=true P(i,i+1)=(S[i]==S[i+1]
//根据这个思路,我们就可以完成动态规划了,最终的答案即为所有 P(i, j) ==true 中 j-i+1的最大值。
// 注意:在状态转移方程中,我们是从长度较短的字符串向长度较长的字符串进行转移的,因此一定要注意动态规划的循环顺序。

std::string longestPalindrome(std::string s) {
    if ( s.empty() ) {
        return "";
    }
    int n = s.size();
    std::vector<std::vector<bool>> dp(n, std::vector<bool>(n, false));

    int maxLen = 0;
    string maxStr = "";
    for (int j = 0; j < n; ++j ) {
        for (int i = j; i >= 0; --i) {
            if (i == j) {
                dp[i][j] = true;
            }
            else if (i == j - 1) {
                dp[i][j] = dp[i + 1][j] && s[i] == s[j];
            }
            else {
                dp[i][j] = dp[i + 1][j - 1] && s[i] == s[j];
            }

            if ( dp[i][j] && maxLen < j - i +1 ) {
                maxLen = j - i + 1;
                maxStr =  s.substr(i, maxLen);
            }
        }
    }

    return maxStr;
}

int main() {
    string str = "ababba" ;
    string substr = longestPalindrome(str);
    cout<<substr;
    return 0;
}

 

 

//题目:输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最大的一个。
//例如输入数组{32,  321},则输出这两个能排成的最大数字32321.。
//或者输入数组{10,9,33,1000}输出这四个能排列的最大数字933101000.
#include <iostream>
#define MAXSIZE 100
using namespace std;

template<typename T>
class Grial
{
public:
    int Length(int x,int& n)
    {
        n++;
        (x/10)&& (Length(x/=10,n));
        return n;
    }//求数字的位数。
    bool Complate(int x,int y)//比较x,y的大小,是组合排列大小,看xy比yx的大小,从而好形成大堆。
    {
        int _I = 0;
        int i = 0;
        int j = 0;
        int sum_1=x;
        int sum_2=y;
        Length(x,i);
        Length(y,j);
        for(;_I<j;_I++)
        {
            sum_1*=10;
        }
        for(_I=0;_I<i;_I++)
        {
            sum_2*=10;
        }
        if((sum_1+y)>(sum_2+x))return true;
        else
            return false;
    }
    Grial(T a[],int n)
    {
        data = new  T[n];
        size = n;
        for(int i=0;i<n;i++)
        {
            data[i] = a[i];
        }
        int m = size/2;
        while(m<size)
        {
            MaxSort(m);
            m++;
        }
    }
    void MaxSort(int n)//大堆排列
    {
        int temp;
        int i=n;
        int j=(i-1)/2;
        while(i>0)
        {
            if(!Complate(data[j],data[i]))
            {
                temp = data[i];
                data[i]=data[j];
                data[j]=temp;
            }
            i = j;
            j = (i-1)/2;
        }
    }
    int GetTop()//得到大堆第一个元素,并且将最后面一个元算放在下标为0的位置,再进行大堆排序.
    {
        if(size==0)return -1;
        int temp = data[0];
        data[0] = data[size-1];
        size--;
        int m = size/2;
        while(m<size)
        {
            MaxSort(m);
            m++;
        }
        return temp;
    }
    void GetSum()
    {
        int i = GetTop();
        if(i!=-1)
        {
            cout<<i;
            GetSum();
        }
    }
private:
    T *data;
    int size;
};
int main()
{
    int a[]={22,223};
    Grial<int> G(a,2);
    G.GetSum();
    cout<<endl;
    return 0;
}

 

 

 

#include <iostream>
#include <vector>
#include "string"
using namespace std;
//构造一个二维数组
//对于一个子串而言,如果它是回文串,并且长度大于2,那么将它首尾的两个字母去除之后,它仍然是个回文串。例如对于字符串ababa,bab也是一个回文串
//根据这样的思路,我们就可以用动态规划的方法解决本题。我们用 P(i,j)表示字符串s的第i到j个字母组成的串是否为回文串:
//P[i,j] = true,表示s[i]-s[j]是回文串.其他情况P[i,j] = false,这里其他情况表示s[i]-s[j]不是回文串或者s[i]到s[j]不合法
//动态规划的状态转移方程:P(i, j) = P(i+1, j-1) && (S[i] == S[j])
//也就是说,只有 s[i+1:j-1]是回文串,并且s[i]==s[j]时才是回文串。
//上文的所有讨论是建立在子串长度大于2,我们还需要考虑动态规划中的边界条件,即子串的长度为1或2。1或2拿出来单独判断。
//我们可以这么推导,P(i,i)=true,然后从0开始探索当前子串的回文串的长度,对比最长的字串。最终的答案即为所有 P(i, j) ==true 中 j-i+1的最大值。

std::string longestPalindrome(std::string s) {
    if ( s.empty() ) {
        return "";
    }
    int n = s.size();
    std::vector<std::vector<bool>> dp(n, std::vector<bool>(n, false));

    int maxLen = 0;
    string maxStr = "";
    for (int j = 0; j < n; ++j ) {
        for (int i = j; i >= 0; --i) {
            if (i == j) {
                dp[i][j] = true;
            }
            else if (i == j - 1) {
                dp[i][j] = dp[i + 1][j] && s[i] == s[j];
            }
            else {
                dp[i][j] = dp[i + 1][j - 1] && s[i] == s[j];
            }

            if ( dp[i][j] && maxLen < j - i +1 ) {
                maxLen = j - i + 1;
                maxStr =  s.substr(i, maxLen);
            }
        }
    }

    return maxStr;
}

int main() {
    string str = "ababba" ;
    string substr = longestPalindrome(str);
    cout<<substr;
    return 0;
}

 

 

 

/题目描述:一个链表,奇数位升序偶数位降序,让链表变成升序的。
//
//比如:1 8 3 6 5 4 7 2 9,最后输出1 2 3 4 5 6 7 8 9
//
//这道题目可以分为三个步骤,
//一:对链表按照奇偶划分,分为一个升序链表 一个降序链表
//二:翻转降序链表
//三:合并两个升序链表

//代码如下:
#include <bits/stdc++.h>
using namespace std;
struct node{
    node * next;
    int val;
    node(int v):val(v), next(NULL){};
};
node * constructList(int *a, int size)
{
    node head(0);
    node * h = &head;
    for(int i=0;i<size;i++)
    {
        h->next = new node(a[i]);
        h = h->next;
    }
    return head.next;
}

void splitList(node * head, node * even, node * odd)
{
    node * e = even;
    node * o = odd;

    int index = 0;
    while(head)
    {
        if(index%2==0)
        {
            e->next = new node(head->val);
            e = e->next;
        }
        else {
            o->next = new node(head->val);
            o = o->next;
        }
        index++;
        head = head->next;
    }
}
node * reverseList(node * head)
{
    node * pre = NULL;
    node * cur = head;
    while(cur)
    {
        node * temp =  cur->next;
        cur->next = pre;
        pre = cur;
        cur = temp;
    }
    return pre;
}
node * mergeList(node * h1, node * h2)
{
    node head(0);
    node * h = &head;
    while(h1 && h2)
    {
        if(h1->val < h2->val)
        {
            h->next = h1;
            h1 = h1->next;
        }
        else {
            h->next = h2;
            h2 = h2->next;
        }
        h = h->next;
    }
    if(!h1) h->next = h2;
    else h->next = h1;
    return head.next;
}
int main()
{
    int num[] = {1,20,2,18,3,16,4,5,5,3,7,2};
    node * h1 = constructList(num,12);
    node even(0);
    node odd(0);
    node * e = &even;
    node * o = &odd;
    splitList(h1, e, o);
    node * ecopy = e->next;
    while(ecopy)
    {
        cout << ecopy->val <<  " ";
        ecopy = ecopy->next;
    }
    cout << "e" << endl;
    node * ocopy = o->next;
    while(ocopy)
    {
        cout << ocopy->val << " ";
        ocopy = ocopy->next;
    }
    cout << "o" << endl;

    node * h2 = reverseList(o->next);
    node * h3 = mergeList(e->next, h2);
    while(h3)
    {
        cout << h3->val << " ";
        h3 = h3->next;
    }

    return 0;
}
#include <atomic>
#include <condition_variable>
#include <functional>
#include <memory>
#include <mutex>
#include <queue>

template <class T>

class CQueue
{
protected:
    // Data
    std::queue<T> _queue;   ///< 存储数据的真实队列, 不是线程安全的
private:
    typename std::queue<T>::size_type _size_max;    ///< 队列的最大长度
    // Thread gubbins
    std::mutex _mutex;  ///<  线程操作 锁
    std::condition_variable _fullQue;   ///< 队列满了的信号
    std::condition_variable _empty; ///< 队列为空的信号

    // Exit
    // 原子操作
    std::atomic_bool _quit; ///< { false };     // 退出信号
    std::atomic_bool _finished; ///< { false }; // 完成信号 // 表示不再继续输入数据

public:
    //初始化队列
    CQueue(const size_t size_max) :_size_max(size_max) {
        _quit = ATOMIC_VAR_INIT(false);
        _finished = ATOMIC_VAR_INIT(false);
    }

    ~CQueue()
    {
        Quit();
        while (_queue.size())
            ;
    }
    //队列中加入新的 对象  根据情况决定 满信号之后 新数据丢弃或者等待
    bool Push(T& data)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        while (!_quit && !_finished)
        {
            if (_queue.size() < _size_max)
            {
                _queue.push(std::move(data));
                //_queue.Push(data);
                _empty.notify_all();
                return true;
            }
            else
            {
                // wait的时候自动释放锁,如果wait到了会获取锁
                _fullQue.wait(lock);
                // return false;   ///< 如果满了 这里不进行等待 避免出现问题
            }
        }

        return false;
    }

    //返回队列最前面的元素 并且弹出
    //如果空 如果finish 则直接返回fasle 否则 等待队列加入元素
    bool Pop(T &data)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        while (!_quit)
        {
            if (!_queue.empty())                // 队列非空
            {
                //data = std::move(_queue.front());
                data = _queue.front();
                _queue.pop();

                _fullQue.notify_all();       // 通知所有 由于满队无法加入的线程
                return true;
            }
            else if (_queue.empty() && _finished)   // 队列为空 且不再加入
            {
                return false;
            }
            else
            {
                // _empty.wait(lock);          // 等待队列加入元素
                return false;   ///< 不等待元素加入数据
            }
        }
        return false;
    }

    /**
     * @fn  std::shared_ptr<T> CQueue::Pop(void)
     *
     * @brief   弹出一个元素 直接返回  出错无法报错
     *
     * @author  IRIS_Chen
     * @date    2019/10/14
     *
     * @return  The previous top-of-stack object.
     */

    std::shared_ptr<T> Pop(void)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        std::shared_ptr<T> res = nullptr;
        while (!_quit)
        {
            if (!_queue.empty())                // 队列非空
            {
                //data = std::move(_queue.front());
                res = std::make_shared<T>(_queue.front());
                _queue.pop();

                _fullQue.notify_all();       // 通知所有 由于满队无法加入的线程

                return res;
            }
            else if (_queue.empty() && _finished)   // 队列为空 且不再加入
            {
                return res;     // 无数据进入 智能返回一个空指针 (可能出错)
            }
            else
            {
                _empty.wait(lock);          // 等待队列加入元素
            }
        }
        return false;
    }

    /**
     * @fn  void CQueue::Finished()
     *
     * @brief   The queue has Finished accepting input 标识队列完成输入 不再继续输入
     *
     * @author  IRIS_Chen
     * @date    2019/10/14
     */

    void Finished()
    {
        _finished = true;
        _empty.notify_all();
    }

    void Quit()
    {
        _quit = true;
        _empty.notify_all();
        _fullQue.notify_all();
    }

    int Length()
    {
        std::unique_lock<std::mutex> lock(_mutex);
        return static_cast<int>(_queue.size());
    }
    int Size()
    {
        std::unique_lock<std::mutex> lock(_mutex);
        return static_cast<int>(_queue.size());
    }


    bool Empty(void)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        return (0 == _queue.size());
    }

    bool Clear(void)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        while (!_queue.empty ())
        {
            Pop();  // 依次弹出数据
        }
        return true;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值