【编程题目】有 n 个长为 m+1 的字符串,如果某个字符串的最后 m 个字符与某个字符串的前 m 个字符匹配...

37.(字符串)
有 n 个长为 m+1 的字符串,
如果某个字符串的最后 m 个字符与某个字符串的前 m 个字符匹配,则两个字符串可以联接,
问这 n 个字符串最多可以连成一个多长的字符串,如果出现循环,则返回错误。

分析:如果出现循环,则返回错误 这句不懂

具体做法是先给每个字符串建一个vector 存入每个字符串后面可以匹配的字符串序号

然后遍历所有的搭配情况,找到最长的。

我的遍历代码很丑... 可谓又臭又长..... 深深的自我鄙视。

/*
37.(字符串)
有 n 个长为 m+1 的字符串,
如果某个字符串的最后 m 个字符与某个字符串的前 m 个字符匹配,则两个字符串可以联接,
问这 n 个字符串最多可以连成一个多长的字符串,如果出现循环,则返回错误。
start time = 18:27
end time =
*/

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

//判断两个字符串能否拼接 0表示不能 2表示s1在前 1表示s2在前
int contact(string s1, string s2, int m)
{
    if(s1.substr(0, m) == s2.substr(s2.length() - m, m))
        return 1;
    else if(s2.substr(0, m) == s1.substr(s1.length() - m, m))
        return 2;
    else
        return 0;
}

void getMax0(vector<int> now, vector<vector<int>> can_compare, vector<int> &max)
{
    bool isfind = false;
    int last = now.back();
    vector<int>::iterator it;
    for(it = can_compare.at(last).begin(); it < can_compare.at(last).end(); it++)
    {
        bool isHave = false;
        vector<int>::iterator it2;
        for(it2 = now.begin(); it2 < now.end(); it2++)
        {
            if((*it) == (*it2))
            {
                isHave = true;
                break;
            }
        }
        if(isHave == false)
        {
            isfind = true;
            now.push_back(*it);
            getMax0(now, can_compare, max);
            now.pop_back();
        }
    }

    if(isfind == false)
    {
        if(now.size() > max.size())
        {
            max = now;
        }
    }
}
vector<int> getMax(vector<vector<int>> can_compare)
{
    vector<int> contact;
    vector<int> max;
    vector<int> now;
    vector<vector<int>>::iterator it;
    for(int i = 0; i < can_compare.size(); i++)
    {
        now.push_back(i);
        getMax0(now, can_compare, max);
        now.clear();
    }

    return max;
}

//返回可能的最大长度
string maxLength(vector<string> S, int m)
{
    //找到每个字符串在前时有哪些其他字符串可以与其匹配
    vector<vector<int>> can_compare;
    vector<string>::iterator it;
    for(it = S.begin(); it < S.end(); it++)
    {
        vector<int> can_member;
        vector<string>::iterator it2;
        int n = 0;
        for(it2 = S.begin(); it2 < S.end(); it2++)
        {
            if(it != it2)
            {
                if(contact(*it, *it2, m) == 2)
                {
                    can_member.push_back(n);
                }
            }
            n++;
        }
        can_compare.push_back(can_member);
    }

    vector<int> maxStringMember = getMax(can_compare);

    vector<int>::iterator it3;
    string ans = S.at(maxStringMember.at(0));
    for(it3 = maxStringMember.begin() + 1; it3 < maxStringMember.end(); it3++)
    {
        string after = S.at(*it3);
        ans.append(after.substr(after.length() - 1, 1));
    }

    cout << "the max length is "<< ans.length() << endl;
    cout << "the string is " << ans << endl;
    return ans;
}

int main()
{
    vector<string> S;
    string s1 = "abd";
    S.push_back(s1);
    string s2 = "bcd";
    S.push_back(s2);
    string s3 = "cde";
    S.push_back(s3);
    string s4 = "def";
    S.push_back(s4);

    string ans = maxLength(S, 2);

    return 0;
}

在网上看答案,发现这是一道图的题。还没研究,明天仔细看看。

时间: 2024-12-07 02:03:21

【编程题目】有 n 个长为 m+1 的字符串,如果某个字符串的最后 m 个字符与某个字符串的前 m 个字符匹配...的相关文章

【编程题目】最长公共字串

56.最长公共字串(算法.字符串).题目:如果字符串一的所有字符按其在字符串中的顺序出现在另外一个字符串二中,则字符串一称之为字符串二的子串.注意,并不要求子串(字符串一)的字符必须连续出现在字符串二中.请编写一个函数,输入两个字符串,求它们的最长公共子串,并打印出最长公共子串.例如:输入两个字符串 BDCABA 和 ABCBDAB,字符串 BCBA 和 BDAB 都是是它们的最长公共子串,则输出它们的长度 4,并打印任意一个子串. 经典动态规划题. #include <stdio.h> #i

【编程题目】求一个数组的最长递减子序列 比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5, 4,3,2}

47.创新工场(算法):求一个数组的最长递减子序列 比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5,4,3,2} 思路:动态规划 从最后一个数字开始,计算以当前数字其实的序列的最长递减子序列. 每次找最长子序列,都扫描它之前求得的子序列中最长,且第一个数字比当前数字小的. 如: 第一个数字 2, 最大长度 1, 下一个数字是 第 7 个 第二个数字 3,  最大长度 2, 下一个数字是 第 7 个 第三个数字 4,  最大长度 3, 下一个数字是 第 6 个 第四个数字 5, 

火车调度-c#求解-英雄会在线编程题目

题目: 火车调度 返回首页 发布公司: 有 效 期: 赛 区: CSDN 2014-04-30至2015-04-30 北京 难 度 等 级: 答 题 时 长: 编程语言要求: 120分钟 C C++ Java C# 题目详情 火车从A地和B地之间运行,你知道火车从某地出发的时间和到达某地的时间(这个时间出发,一定这个时候到达).火车到达目的地后,不能立刻返回,需要经过t分钟检修才可以返回.列车只在A.B两地运行.你知道每天内的时刻表,求A,B两地各需要存放多少辆列车,才能满足这个时刻表?即只要该

【编程题目】对于一个整数矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右)某一个元素也加一

45.雅虎(运算.矩阵):1.对于一个整数矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右)某一个元素也加一,现给出一正数矩阵,判断其是否能够由一个全零矩阵经过上述运算得到. 这道题,是我目前为止做过的最最最最最麻烦.最繁琐的题目了. 思路: 把输入的矩阵一步步还原成 0 矩阵 一个数字,只可能伴随着它上下左右四个方向的数字变化. ①如果数字比它周围四个数的和要大,那么一定不满足条件. ②如果数字小于等于四周的数字和,且其四周仅有一个数字不为0: 不为0的那个周围数字的大小 -=

【编程题目】把数组排成最小的数

68.把数组排成最小的数(数组.算法).题目:输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个.例如输入数组{32, 321},则输出这两个能排成的最小数字 32132.请给出解决问题的算法,并证明该算法. 思路:首先,肯定要考虑溢出问题.开始想用字符串,后来改为了用list.思路是先把第一个数字放入list,然后依次把后面的数字插入到合适的位置. 关键问题就是如何判断两个数字哪一个在前面. ①对于 353 .412这样的情况,肯定是第一个数字小的在前面 ②遇到数字

F(X)--c#求解-英雄会在线编程题目

先看题目: F(X) 发布公司: 有 效 期: 赛 区: CSDN 2014-04-16至2015-04-16 北京 难 度 等 级: 答 题 时 长: 编程语言要求: 120分钟 C C++ Java C# 题目详情 我们定义 F(x)是满足 x  mod(a*b) == 0这样的a,b的组数.现在给你一个n,你需要求出 F(n) 输入格式: 多组数据,每组第一行有一个整数n, 0 < n <= 10^11. 输出格式: 每组输出一行,满足条件的(a,b)对数 答题说明 输入样例 1 2 3

【目录】编程题目

编程题目 如何对n个数进行排序,要求时间复杂度O(n),空间复杂度O(1) 一个数组是由一个递减数列左移若干位形成的,在这种数组中查找某一个数.☆ 请修改 append 函数,利用这个函数实现两个非降序链表的并集 一串首尾相连的珠子(m 个),有 N 种颜色(N<=10),取出其中一段,要求包含所有 N 中颜色,并使长度最短. 求一个有向连通图的割点,割点的定义是,如果除去此节点和与其相关的边, 有向图不再连通 有 n 个长为 m+1 的字符串,如果某个字符串的最后 m 个字符与某个字符串的前

【编程题目】二元树的深度

52.二元树的深度(树).题目:输入一棵二元树的根结点,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度.例如:输入二元树: 10/ \6 14/ / \4 12 16输出该树的深度 3.二元树的结点定义如下:struct SBinaryTreeNode // a node of the binary tree{int m_nValue; // value of nodeSBinaryTreeNode *m_pLeft; // left ch

编程题目分类(剪辑)

1. 编程入门 2. 数据结构 3. 字符串 4. 排序 5. 图遍历 6. 图算法 7. 搜索:剪枝,启发式搜索 8. 动态规划/递推 9. 分治/递归 10. 贪心 11. 模拟 12. 算术与代数 13. 组合问题 14. 数论 15. 网格,几何,计算几何 [编程入门] PC 110101, uva 100, The 3n+1 problem, 难度 1 PC 110102, uva 10189, Minesweeper, 难度 1 PC 110103, uva 10137, The T