排列若干个字符串,判断是否首尾可以连接在一起

给出一个二维的字符串,即n行一列,如array[4][1] = {“def”,”abc”,”cmd”,”fkl”};取出每个字符串的首尾字符,进行判断是否可以形成首尾相连,array数组中取出的分别为:“df”,”ac”,”cd”,”fl”,可以形成a->c->c->d->d->f->f->l,因此我们判断得出结论上述输入可以形成首尾相连.这里我们要注意的是从数组中取出首尾字符后要进行所有可能的排列,然后判断是否可以形成首尾相连。
这里我们给出两种方法,第一种利用STL中的相关函数实现

方法一:使用vector

//排列若干个字符串,检查字符串是否收尾相接,若是返回1,否则返回-1
bool  seriesarray(char** array,int row,int column)
{  
    using namespace std;
    bool result  = false;
    if(array == NULL || row <= 0 || column <= 0)
        return result;

    //array[4][5]={"degf","abc","fgh","chd"};
    int num = row;//定义一个变量表示字符串的个数
    vector<char>v;//生成row*2个对象
    for (int i = 0;i < row;i++)
    {
        //将每个字符串的第一个元素和最后一个元素插入到temp中
        v.push_back(array[i][0]);
        v.push_back(array[i][strlen(array[i])-1]); 
    }
    vector<char>::iterator iter; //iterator 抽象了指针的绝大部分基本特征* 
    printf("输出每一个字符串的首尾字符: ");
    for( iter = v.begin(); iter != v.end(); iter++ )   
            printf("%c",*iter) ; 
    printf("\n");


    vector<char>temp(v);
    vector<char>out;//结果放在out中
    out.reserve(row*2);
    out.push_back(v[0]);//array[0][0]///给out[0]和out[1]赋值
    out.push_back(v[1]);//array[0][strlen(array[0])-1]/

    //vector<char>::iterator itor = temp.begin();
    temp.erase(temp.begin());
    temp.erase(temp.begin());//删除前两个字母
    num--;

    //判断,一个字符串的头是否是另外几个的尾部,且头部所在的为偶数(从0开始),尾部所在的下标为奇数
    //分成三部分,1.out[0],out[1]在头部,即out[0]不是其余某一个字符的尾部,而out[1]是其余某一个的头部;
    //2.out[0],out[1]在中部,out[0]是其余某一个的尾部,out[1]是其余某一个的头部;
    //3.out[0],out[1]在尾部,out[0]是某一字符的尾部,out[1]是结束部分;
    while (num != 0)
    {
        int flag = num;
        int i = 0;
        for ( i = 0;i < (int)temp.size()/2;i++)
        {
          if (*out.rbegin() == temp[2*i])//以out[1]为开始,将其插入在out[1]的后面
           {
            out.push_back(temp[2*i]);
            out.push_back(temp[2*i+1]);

            int pre = temp[2*i];
            int after = temp[2*i+1];    //因为下面的erase操作会改变temp的大小,因此将其保存
            vector<char>::iterator del0 = find(temp.begin(),temp.end(),pre);
            if(del0 != temp.end())
                temp.erase(del0);
            vector<char>::iterator del1 = find(temp.begin(),temp.end(),after);
            if(del1 != temp.end())
                temp.erase(del1);
             num--;
             i = 0;
           }
        }
        for(i = 0;i < (int)temp.size()/2;i++)
        {
          if (*out.begin() == temp[2*i+1])//以out[0]为开始,将其插入在out[0]的前面
          {
              out.insert(out.begin(),temp[2*i+1]);
              out.insert(out.begin(),temp[2*i]);
              int pre = temp[2*i];
              int after = temp[2*i+1];
              vector<char>::iterator del0 = find(temp.begin(),temp.end(),pre);
              if(del0 != temp.end())
                  temp.erase(del0);
              vector<char>::iterator del1 = find(temp.begin(),temp.end(),after);
              if(del1 != temp.end())
                  temp.erase(del1);
              num--;
              i = 0;
          }
        }
        if(flag == num)
        {
          result = false;
          break;
        }

    }
    if (num == 0 && temp.empty() )
         result = true;

    return result;
}

方法二:使用暴力方法,比较笨拙

bool  seriesarray(vector<string>  &vec, int str_nums)
{
    bool result = false;
    vector<int> com(str_nums,0);
    for (int i = 0; i < str_nums; i++)
        com[i] = i;                    //共str_num个字符串
    int facn = getfaci(str_nums);      //共有facn这么多种组合,facn = str_nums!的阶乘

    for (int i = 0; i < facn && !result;i++)
    {
        int j = 1;
        for (; j < str_nums; j++)
        {
            int pre_pos = com[j - 1];
            int cur_pos = com[j];
            if (vec[cur_pos][0] != vec[pre_pos][vec[pre_pos].size() - 1])
                break;
        }
        if (j == str_nums)
            result = true;
        next_permutation(com.begin(), com.end());//对com[]中的元素进行全排列
    }

    return result;
}

int getfaci(int n)
{
    int result = 1;
    for (int i = 1; i <= n; i++)
        result *= i;
    return result;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值