标题:反转字符串遇到的问题
只看楼主
EMMMM
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2017-9-16
结帖率:75%
已结贴  问题点数:20 回复次数:8 
反转字符串遇到的问题
我找到了一个求最长公共子序列的程序,想把他修改一下变成求最长回文子序列的程序,直接把程序中输入的数组str1反转变成str2,但是当我用strcpy(str2,strrev(str1))之后,发现str2确实被反转了,但同时输出的结果也不对了,直接变成了被反转的str1,当我把反转语句strcpy(str2,strrev(str1))删掉,用gets语句自己在控制台逆序输入一遍str1,程序的结果又正确了,这是什么情况??求大神解释
代码如下
#include <stdio.h>  
#include <string.h>  
#include <stdlib.h>  
#include <cstring>  
int LCSLength(char* str1, char* str2, int **b)
{
    int i, j, length1, length2, len;
    length1 = strlen(str1);
    length2 = strlen(str2);

    //双指针的方法申请动态二维数组  
    int **c = new int*[length1 + 1]; //共有length1+1行  
    for (i = 0; i < length1 + 1; i++)
        c[i] = new int[length2 + 1];//共有length2+1列  

    for (i = 0; i < length1 + 1; i++)
        c[i][0] = 0;        //第0列都初始化为0  
    for (j = 0; j < length2 + 1; j++)
        c[0][j] = 0;        //第0行都初始化为0  

    for (i = 1; i < length1 + 1; i++)
    {
        for (j = 1; j < length2 + 1; j++)
        {
            if (str1[i - 1] == str2[j - 1])//由于c[][]的0行0列没有使用,c[][]的第i行元素对应str1的第i-1个元素  
            {
                c[i][j] = c[i - 1][j - 1] + 1;
                b[i][j] = 0;          //输出公共子串时的搜索方向  
            }
            else if (c[i - 1][j]>c[i][j - 1])
            {
                c[i][j] = c[i - 1][j];
                b[i][j] = 1;
            }
            else
            {
                c[i][j] = c[i][j - 1];
                b[i][j] = -1;
            }
        }
    }
    /*
    for(i= 0; i < length1+1; i++)
    {
    for(j = 0; j < length2+1; j++)
    printf("%d ",c[i][j]);
    printf("\n");
    }
    */
    len = c[length1][length2];
    for (i = 0; i < length1 + 1; i++)    //释放动态申请的二维数组  
        delete[] c[i];
    delete[] c;
    return len;
}
void PrintLCS(int **b, char *str1, int i, int j)
{
    if (i == 0 || j == 0)
        return;
    if (b[i][j] == 0)
    {
        PrintLCS(b, str1, i - 1, j - 1);//从后面开始递归,所以要先递归到子串的前面,然后从前往后开始输出子串  
        printf("%c", str1[i - 1]);//c[][]的第i行元素对应str1的第i-1个元素  
    }
    else if (b[i][j] == 1)
        PrintLCS(b, str1, i - 1, j);
    else
        PrintLCS(b, str1, i, j - 1);
}

int main(void)
{
    char str1[100], str2[100];
    int i, length1, length2, len;
    printf("请输入第一个字符串:");
    gets_s(str1);
    strcpy_s(str2, _strrev(str1));//这里原来是gets(str2)
    puts(str2);
    length1 = strlen(str1);
    length2 = strlen(str2);
    //双指针的方法申请动态二维数组  
    int **b = new int*[length1 + 1];
    for (i = 0; i < length1 + 1; i++)
        b[i] = new int[length2 + 1];
    len = LCSLength(str1, str2, b);
    printf("最长公共子序列的长度为:%d\n", len);
    printf("最长公共子序列为:");
    PrintLCS(b, str1, length1, length2);
    printf("\n");
    for (i = 0; i < length1 + 1; i++)//释放动态申请的二维数组  
        delete[] b[i];
    delete[] b;
    system("pause");
    return 0;
}
搜索更多相关主题的帖子: int new for i++ printf 
2018-04-05 16:43
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:20 
是指
str1

abcdsfdcba

str2
abcdfsdcba

结果
abcd

这样么~

回文串反转过来的结果还是回文串,但这个算法找到的最长子串却不一定是回文串~
回文串匹配类似KMP算法,不过要修改一下匹配模式,记得网上可以找到相关匹配算法还是老老实实实地从回文串的性质下手比较好~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2018-04-05 17:56
EMMMM
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2017-9-16
得分:0 
回复 2楼 九转星河
不是这个问题,是假如str1是character,这个程序会直接输出retcarahc,但是如果改成gets(str2),然后倒着输入一遍character,他会给出正确的carac
2018-04-05 19:51
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 3楼 EMMMM
那就合理了~
虽然我没有用过,但我查过一下那个函数参数是char*而不是const char*
这个细节说明了str1的内容被修改了,如果是const char*则意味着是动态分配空间到时要释放内存~

可以这样,试试_strrev(strcpy(str2,str1));那就没事了~

而且我还以为子串是连续的,如果不连续的话就没啥事了~

[此贴子已经被作者于2018-4-5 20:22编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2018-04-05 20:17
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
关于子串是否连续这个问题~然后我搜了一下"子串"的定义~

子串
串中任意个连续的字符组成的子序列称为该串的子串

中文名
子串
内    容
连续的字符
内容1
adereegfbw
要    点
非空子串


是要连续的,但你那个carac明显不是主串里面的任何一个子串(当然可以当这个是题外话),就先这样了~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2018-04-05 20:30
EMMMM
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2017-9-16
得分:0 
回复 4楼 九转星河
我把语句改成了_strrev(strcpy_s(str2, str1));但VS2015编译器提醒我:无法将参数 1 从“errno_t”转换为“char *”这个您知道是什么错误吗?另外谢谢您指出const这个事,我把这个给忘了
2018-04-05 20:31
EMMMM
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2017-9-16
得分:0 
回复 5楼 九转星河
子串这个我表述有问题,我得作业是求子序列,只要标号递增不连续也行,子串肯定是要连续的,而且肯定不能用我这种“投机取巧”的方法做子串的做法就是用您说的KMP匹配做。。。
2018-04-05 20:33
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 6楼 EMMMM
那个_s类型的的我没有用过不太清楚,应该是返回类型不匹配(貌似是返回值是一个状态信息),不过大体思路就是先复制字符串然后再转置这样试试~

[此贴子已经被作者于2018-4-5 20:58编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2018-04-05 20:53
EMMMM
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2017-9-16
得分:0 
回复 8楼 九转星河
ok,谢谢您了
2018-04-05 21:22



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-485779-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.366552 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved