关于最短分割回文的实现

来源:互联网 发布:多益网络行政薪资 编辑:程序博客网 时间:2024/06/06 04:18

leetcode 上源题目是这样的


Given a string s, partition s such that every substring of the partition is a palindrome.

Return the minimum cuts needed for a palindrome partitioning of s.

For example, given s = "aab",
Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut.


给定一个字符串 s,分割s,使其每个子串都是回文(所谓回文就是reverse运算后和以前一样)


返回 分割字符串所需要的最小次数(最大次数就是字符串长度-1,因为每个单独的字符都是回文)


我第一个思路,从左侧开始,选择最大的子串,然后接着向下分,应该得到最小(没有理论支持,我只是猜想,经测试,思路完全不对)

比如eeeye, 经过我的分割,eee,y,e 肯定不对,应该是ee,eye 同理从右侧开始也不对。

第二个思路和第一个一样,从左到右一次,从右到左一次,谁小取谁(同样没有理论支持,经过测试,依然无效)

测试字符串如下 “adabdcaebdcebdcacaaaadbbcadabcbeabaadcbcaaddebdbddcbdacdbbaedbdaaecabdceddccbdeeddccdaabbabbdedaaabcdadbdabeacbeadbaddcbaacdbabcccbaceedbcccedbeecbccaecadccbdbdccbcbaacccbddcccbaedbacdbcaccdcaadcbaebebcceabbdcdeaabdbabadeaaaaedbdbcebcbddebccacacddebecabccbbdcbecbaeedcdacdcbdbebbacddddaabaedabbaaabaddcdaadcccdeebcabacdadbaacdccbeceddeebbbdbaaaaabaeecccaebdeabddacbedededebdebabdbcbdcbadbeeceecdcdbbdcbdbeeebcdcabdeeacabdeaedebbcaacdadaecbccbededceceabdcabdeabbcdecdedadcaebaababeedcaacdbdacbccdbcece” 测试结果应该273,我得到的281。

思路不清晰,没有理论支持,上网搜索,有个最大回文切割(从字符串中切割出最大回文,递归其左面和右面),实验之,结果还是不对。

具体例子记不清楚了。


冥思苦想:总结如下理论 从a - b 是回文,从图的角度看 a-b的权重是1 ,所以可以用最短路径方法解决,coding,测试发现问题在于,当节点过多时,循环量过大,采用递归递归太多层把内存爆掉,不采用递归也不行,时间过长。


优化程序,abcdefghijklmnopqrstuvwxyz 这样每个都是单独字母的改成这样的图结果 a-z 权重26 ,只有a-z是关键节点。最后终于搞定

程序如下



include<stdio.h>

//defined struct ;
typedef struct Node{
        int from;
   int to;
int weight;
struct Node* next;
} node,*pnode;
// pc is the string`s first character ,length is s.lengt   
int isPalindrome(char* bc, int length){
    if (1 == length) return 1;
    int l = length/2;
    int i = 0;
    for (;i<=l;i++){
       if (*(bc+i) != *(bc+length-i-1))
       return 0;
    }
    return 1;
}

//it not used is this programer,but it is still useful ,So i need to keep it here.
int caculate(pnode phead , int i,int length)
{
    pnode pcurrent = phead + i;
int min =  length;
while(NULL != pcurrent)
    {
   if(length == pcurrent->to)
return pcurrent->weight;
int ways = pcurrent->weight+caculate(phead,pcurrent->to,length);
        printf("choose ways is from %d--------->%d ,ways is %d\n",pcurrent->from,pcurrent->to,ways);  
if( min > ways){
min = ways;
}
   pcurrent = pcurrent->next;
}
return min;
}
int main()
{

    char* pc = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    int length = 1462;//actually i can caculate the length ,but i do like to do that .
int* path = (int *)malloc(sizeof(int)*length*length); //why malloc ,because in stack ,we can just use 1M for array,
node keyNode[length] ;
memset(path,0,sizeof(int)*length*length);
    memset(keyNode,0,sizeof(node)*length);    
    int i=0,j;
    for (;i<length;i++)
    {
        j = i+1;
int k = 0;
        for (;j<=length;j++)
        {
                        
            if (isPalindrome(pc+i,j-i))
            {
              *(path+k*length+i) = j;
 k++;
            } 
        }
    }//all path here 
    /* print for debug
int p=0,q;
    for (;p<length;p++)
    {
       q = 0;
       for (;q<length;q++)
       {
           printf("%2d,",path[p][q]);
       }
       printf("\n");
    }
*/
i = 0;
    for(;i<length-1;i++)
{   
   pnode phead = keyNode+i;
   if(0 ==  *(path+length+i) ){
   int weight = 1;
int next = i +1;

while(0 == *(path+length+next) && next < length ){
   weight++;
next++;
}
phead->from = i;
phead->to = next;
phead->weight = weight;
phead->next = NULL;
}else{

    int row = 0;
pnode previous = phead;
int init = 1; 
while(0 != *(path+length*row+i) && row < length)
{   
    if(previous == phead && init)
{
  phead->from = i;
phead->to =  *(path+length*row+i);
phead->weight = 1;
phead->next = NULL; 
}else{
   pnode pcurrent = (pnode)malloc(sizeof(node));
pcurrent->from = i;
pcurrent->to = *(path+length*row+i);
pcurrent->weight = 1;
pcurrent->next = NULL;
previous->next = pcurrent;
previous = previous->next;
}
row++;
init = 0;
}
 
}
}
printf("length is %d\n",length);
keyNode[length-1].from = length -1 ;
keyNode[length-1].to = length  ;
keyNode[length-1].weight = 1;
keyNode[length-1].next = NULL;


//full all keyNode Pointer

int keyPath[length+1] ;
memset(keyPath,0,sizeof(int)*(length+1));
int flag = 1 ;
keyPath[0] = 1;
while(flag)
{
flag = 0;
   i = 0;
for(;i<=length;i++)
{
if(0 != keyPath[i])
{
   if(i == length){
   keyPath[i] = 1;
break;
}
pnode pcn = &keyNode[i];
while(NULL != pcn)
{
if(0 == keyPath[pcn->to])
{
keyPath[pcn->to] = 1;
flag = 1;
}
pcn = pcn->next;
}
}
}
}
/find out all key Path node
/*
pnode link = keyNode;
pnode pcn = link;
pnode pen = link;
printf("begin\n");
while(NULL != pen->next)
{
   printf("middle\n");
   pen = pen->next;
}
printf("link is %0x\n",link);
printf("pen is %0x\n",pen);
printf("pen1 is %0x\n",keyNode);


while (NULL != pcn )
{
   printf("pcn is %0x\n",pcn);
printf("---keynode = is %0x---\n",keyNode);
        if(0 == keyPath[pcn->to]){
keyPath[pcn->to] = 1;
pen->next = &keyNode[pcn->to];
}
        while(NULL != pen->next)
{
   printf("hello");
pen = pen->next;
}
pcn = pcn->next;
}
    pen = link;
while (pen != NULL)
{
printf("kenNode is from %d --------->%d,-------weight = %d\n",pen->from,pen->to,pen->weight);
pen = pen->next;
}*/
i = 0;
for(;i<=length;i++)
{
if(0 != keyPath[i])
printf("%d is the keyPathNode\n",i);
}
int keyDis [length+1] ;
memset(keyDis,0,(length+1)*sizeof(int));
    i = 0;
for (;i<=length;i++)
{
if(0 != keyPath[i])
{
pnode pkn = &keyNode[i];

while(NULL != pkn && pkn->from == i)
{
           
if(0 == keyDis[pkn->to] )
{
keyDis[pkn->to] = keyDis[i] + pkn->weight;
}else{
   keyDis[pkn->to]=keyDis[pkn->to] > keyDis[i] + pkn->weight ?keyDis[i] + pkn->weight:keyDis[pkn->to];
}
pkn = pkn->next;
}
}
}
i = 0;
for(;i<=length;i++)
{
if(0 != keyDis[i])
printf("0---------------%d is ------------%d\n",i,keyDis[i]);
}

//printf("give me the right result is %d",caculate(keyNode,0,length));
    return 0;
}



总结,这实际是最短路径的一种实现。

通过搞这个破玩意,总结自己的不足 1 太懒,有想法不愿意去实现,经常打完while(){}后不愿意往里写东西

                                                                 2 改代码时不备份,最后想返回没地方找去,老得再写,看来再小的东西用个svn,cvs,git也必要

                                                                 3 c++应该学学了,老用c也不是那么回事

原创粉丝点击